From 396c7fbc6776b8225da84268a46537645fcb1f1d Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 00:42:39 +0000 Subject: [PATCH 01/26] feat: scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools Add a ChatGptDesktopAdapter with a local-only CDP implementation, DOM selectors in one module, macOS relaunch helper, chatgpt_desktop_* MCP tools, gbot chatgpt-desktop CLI commands, and app-server fallback that reports backend. Includes rstest coverage with a fake adapter and a minor changeset. Co-authored-by: Zack Jackson --- .changeset/chatgpt-desktop-cdp.md | 5 + README.md | 16 +- docs/chatgpt-desktop-cdp.md | 64 ++++ src/cli/chatgpt-desktop/read.tsx | 55 +++ src/cli/chatgpt-desktop/send.tsx | 51 +++ src/cli/chatgpt-desktop/status.tsx | 40 +++ src/cli/chatgpt-desktop/threads.tsx | 59 ++++ src/core/chatgpt-desktop/adapter.ts | 26 ++ .../chatgpt-desktop/app-server-fallback.ts | 188 +++++++++++ src/core/chatgpt-desktop/cdp-adapter.ts | 251 ++++++++++++++ src/core/chatgpt-desktop/cdp-dom.ts | 275 +++++++++++++++ src/core/chatgpt-desktop/cdp-session.ts | 190 +++++++++++ src/core/chatgpt-desktop/errors.ts | 42 +++ src/core/chatgpt-desktop/facade.ts | 162 +++++++++ src/core/chatgpt-desktop/index.ts | 63 ++++ src/core/chatgpt-desktop/loopback.ts | 64 ++++ src/core/chatgpt-desktop/relaunch.ts | 75 +++++ src/core/chatgpt-desktop/routes.ts | 178 ++++++++++ src/core/chatgpt-desktop/types.ts | 75 +++++ .../tools/chatgpt_desktop_list_threads.tsx | 38 +++ .../tools/chatgpt_desktop_read_thread.tsx | 39 +++ .../grok-bot/tools/chatgpt_desktop_send.tsx | 40 +++ .../grok-bot/tools/chatgpt_desktop_status.tsx | 40 +++ .../tools/chatgpt_desktop_wait_reply.tsx | 40 +++ test/host-tool-inventory.test.js | 12 +- tests/route-unit/chatgpt-desktop.test.ts | 316 ++++++++++++++++++ tests/route-unit/tools.test.ts | 2 +- 27 files changed, 2403 insertions(+), 3 deletions(-) create mode 100644 .changeset/chatgpt-desktop-cdp.md create mode 100644 docs/chatgpt-desktop-cdp.md create mode 100644 src/cli/chatgpt-desktop/read.tsx create mode 100644 src/cli/chatgpt-desktop/send.tsx create mode 100644 src/cli/chatgpt-desktop/status.tsx create mode 100644 src/cli/chatgpt-desktop/threads.tsx create mode 100644 src/core/chatgpt-desktop/adapter.ts create mode 100644 src/core/chatgpt-desktop/app-server-fallback.ts create mode 100644 src/core/chatgpt-desktop/cdp-adapter.ts create mode 100644 src/core/chatgpt-desktop/cdp-dom.ts create mode 100644 src/core/chatgpt-desktop/cdp-session.ts create mode 100644 src/core/chatgpt-desktop/errors.ts create mode 100644 src/core/chatgpt-desktop/facade.ts create mode 100644 src/core/chatgpt-desktop/index.ts create mode 100644 src/core/chatgpt-desktop/loopback.ts create mode 100644 src/core/chatgpt-desktop/relaunch.ts create mode 100644 src/core/chatgpt-desktop/routes.ts create mode 100644 src/core/chatgpt-desktop/types.ts create mode 100644 src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx create mode 100644 src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx create mode 100644 src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx create mode 100644 src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx create mode 100644 src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx create mode 100644 tests/route-unit/chatgpt-desktop.test.ts diff --git a/.changeset/chatgpt-desktop-cdp.md b/.changeset/chatgpt-desktop-cdp.md new file mode 100644 index 0000000..131bdf3 --- /dev/null +++ b/.changeset/chatgpt-desktop-cdp.md @@ -0,0 +1,5 @@ +--- +"grok-bot-cli": minor +--- + +Scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools (`chatgpt_desktop_*`, `gbot chatgpt-desktop`), with local-only loopback CDP, DOM selectors in one module, and Codex app-server fallback that reports `backend`. diff --git a/README.md b/README.md index c56759c..d67d158 100644 --- a/README.md +++ b/README.md @@ -223,6 +223,19 @@ Residual risks, stated honestly: requests without both matching thread and turn Current shim limitation: Desktop's spawn-time app-tools MCP `-c` overrides are not forwarded to the already-running managed daemon. No restoration path or app-tools parity has been demonstrated here; this is not a claim of permanent protocol impossibility. Fully quit and relaunch ChatGPT.app after install (or login) so it inherits `CODEX_CLI_PATH`. `status` reads the macOS GUI-domain value via `launchctl getenv` (what Desktop actually inherits) alongside the calling shell's value. LaunchAgent persistence is macOS-first; elsewhere install still writes the wrapper and bridge but leaves `CODEX_CLI_PATH` for you to export. `~/.codex/bin` holds scripts only — there is no extra revert note to clean up; revert is `gbot codex desktop-shim uninstall` plus this section. +**ChatGPT Desktop over CDP (scaffold).** Prefer the Desktop UI surface via Chrome DevTools Protocol when you need more than the app-server socket. CDP is **local-only** (`127.0.0.1`); there is no remote transport. Relaunch the macOS app with a debug port (Electron fuses block Node inspect, not Chromium's flag): + +```sh +osascript -e 'tell application "ChatGPT" to quit' \ + && open -a /Applications/ChatGPT.app --args --remote-debugging-port=9222 +gbot chatgpt-desktop status +gbot chatgpt-desktop threads --limit 20 +gbot chatgpt-desktop read +gbot chatgpt-desktop send --thread-id "hello" +``` + +MCP tools: `chatgpt_desktop_status`, `chatgpt_desktop_list_threads`, `chatgpt_desktop_read_thread`, `chatgpt_desktop_send`, `chatgpt_desktop_wait_reply`. List/read/send/wait fall back to the existing Codex app-server client when CDP is down and report `backend: "cdp" | "app-server"`. DOM selectors live in one module (`src/core/chatgpt-desktop/cdp-dom.ts`). Details: [docs/chatgpt-desktop-cdp.md](docs/chatgpt-desktop-cdp.md). + **Status contract (`gbot codex status --json`).** `reachable` is endpoint reachability only. `socketState` is `socket`, `absent`, `permission-denied`, or `not-a-socket`; `mode` is `daemon` for a usable daemon, otherwise the failure: `socket-absent`, `permission-denied` (the file or the connect refused this user), `not-a-socket`, `connect-failed` (socket present, nothing completed the WebSocket upgrade), `handshake-failed` (upgrade or `initialize` failed), `windows-unsupported`, or `bad-response` (reachable, but `initialize` returned something off-schema — `reachable` stays `true`). `schema.compatibility` is `exact` when the daemon reports the pinned version, `unverified` when it differs (methods usually survive upgrades, but the shapes are not re-checked), or `unknown`. `cliVersionProbe` reports whether `codex --version` answered (`ok`, `missing`, `timeout` after 3 s, `error`). The document is always written to stdout and includes `exitCode`; it is `0` only for a usable daemon. `desktopShimConfigured` is true when the installed wrapper is selected by Desktop-facing `CODEX_CLI_PATH` (the GUI domain on macOS). This describes configuration for future launches; a running Desktop may not have inherited it, and the wrapper may have fallen back to stock Codex. `desktopAttached` is `"private-stdio"` when a Desktop-bundled app-server process is observed, otherwise `"unknown"`. That process observation and shim configuration can both be present. Neither a configured shim nor a reachable daemon proves Desktop is attached to that daemon. Verify actual attachment with a controlled shared-thread interaction and matching thread/turn IDs. @@ -258,7 +271,8 @@ that gives Codex, Claude Code, and Cursor a `grok-bot` MCP server with messaging Codex conversation, and managed bridge tools, plus a `talk-to-grok-bot` skill. `gbot_send` and `gbot_thread` handle Grok conversations; `codex_threads`, `codex_send`, `codex_wait`, and `codex_watch` handle Codex conversations. -`gbot_bridge_start`, `gbot_bridge_status`, `gbot_bridge_stop`, and +`chatgpt_desktop_*` tools drive ChatGPT Desktop over local CDP (with app-server +fallback). `gbot_bridge_start`, `gbot_bridge_status`, `gbot_bridge_stop`, and `gbot_codex_respond` manage automatic delivery and scoped operator responses. The tools bundle this repository's gateway client and worker, so the installed plugin does not need `gbot` on `PATH`. diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md new file mode 100644 index 0000000..a01491d --- /dev/null +++ b/docs/chatgpt-desktop-cdp.md @@ -0,0 +1,64 @@ +# ChatGPT Desktop CDP adapter + +`gbot` talks to the ChatGPT / Codex desktop app over the Chrome DevTools +Protocol on **127.0.0.1 only**. There is no remote transport. CDP/DOM details +stay inside `src/core/chatgpt-desktop/`; MCP tools and CLI commands call the +`ChatGptDesktopAdapter` surface. + +## Enable remote debugging (macOS) + +Electron fuses on ChatGPT.app block Node inspect / `RunAsNode`, but they do +**not** block Chromium's `--remote-debugging-port`. The port binds to loopback. + +```sh +# Helper-printed command (also available from the module): +# chatgptDesktopRelaunchCommand({ port: 9222 }) +osascript -e 'tell application "ChatGPT" to quit' \ + && open -a /Applications/ChatGPT.app --args --remote-debugging-port=9222 +``` + +Bundle id: `com.openai.codex`. Do not depend on `@electron/fuses read` — the +framework is renamed (`Codex Framework.framework`) and that tool fails. + +Override the port with `CHATGPT_DESKTOP_CDP_PORT` or `--port`. + +## CLI + +```sh +gbot chatgpt-desktop status +gbot chatgpt-desktop threads --limit 20 +gbot chatgpt-desktop read +gbot chatgpt-desktop send --thread-id "hello" +gbot chatgpt-desktop send "start a new chat with this text" +``` + +## MCP tools + +| Tool | Role | +| --- | --- | +| `chatgpt_desktop_status` | CDP `/json/version` (+ optional attach) and app-server probe | +| `chatgpt_desktop_list_threads` | Sidebar threads via CDP; app-server `thread/list` fallback | +| `chatgpt_desktop_read_thread` | Virtualized timeline harvest; app-server read/items fallback | +| `chatgpt_desktop_send` | Experimental composer submit; app-server send fallback | +| `chatgpt_desktop_wait_reply` | Experimental poll for a new assistant turn | + +Every mutating/list/read result includes `backend: "cdp" | "app-server"`. + +## Target selection + +Prefer CDP `Target.getTargets`. The main window is `type: "page"` with URL +exactly `app://-/index.html`. Ignore avatar-overlay, detached-window, and +chatgpt.com / sandbox webviews. `/json/list` is incomplete and order-unstable; +use it only as a cheap status hint. + +## DOM module + +All selectors live in `src/core/chatgpt-desktop/cdp-dom.ts` (sidebar +`data-app-action-sidebar-thread-*`, timeline scroll, `data-turn-key`, user +bubbles, experimental composer candidates). Do not add selectors elsewhere. + +## Fallback + +When CDP is unreachable, list/read/send/wait/open fall back to the existing +Codex app-server client in `codex-bridge.js` (no duplicated JSON-RPC stack). +Starting a brand-new Desktop thread without a `threadId` still needs CDP. diff --git a/src/cli/chatgpt-desktop/read.tsx b/src/cli/chatgpt-desktop/read.tsx new file mode 100644 index 0000000..5a75a39 --- /dev/null +++ b/src/cli/chatgpt-desktop/read.tsx @@ -0,0 +1,55 @@ +import { Agent } from '@agent-bundle/runtime'; +import type { CliRouteConfig, CliRouteProps } from 'agent-bundle'; +import { z } from 'zod'; + +import { + readThreadOperation, + resultSchema, + resultText, +} from '../../core/chatgpt-desktop/routes.js'; + +export const config = { + description: 'Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).', + exitCode: 'result', + positionals: ['threadId'], + inputJsonSchema: { + additionalProperties: false, + properties: { + limit: { default: 100, type: 'number' }, + port: { type: 'number' }, + threadId: { type: 'string' }, + }, + required: ['threadId'], + type: 'object', + }, +} satisfies CliRouteConfig; + +export const inputSchema = z + .object({ + limit: z.number().int().min(1).max(500).default(100), + port: z.number().int().min(1).max(65535).optional(), + threadId: z.string().min(1).max(256), + }) + .strict(); +export { resultSchema }; + +export default async function chatgptDesktopRead({ + input, +}: CliRouteProps) { + const out = await readThreadOperation(input); + const turns = Array.isArray(out.turns) ? out.turns : []; + const text = + turns.length > 0 + ? turns + .map((turn) => { + const row = turn as { role?: string; text?: string; turnKey?: string }; + return `[${row.role ?? '?'} ${row.turnKey ?? ''}] ${row.text ?? ''}`; + }) + .join('\n\n') + `\n\nbackend: ${String(out.backend ?? '')}` + : resultText(out); + return ( + + {text} + + ); +} diff --git a/src/cli/chatgpt-desktop/send.tsx b/src/cli/chatgpt-desktop/send.tsx new file mode 100644 index 0000000..cf32534 --- /dev/null +++ b/src/cli/chatgpt-desktop/send.tsx @@ -0,0 +1,51 @@ +import { Agent } from '@agent-bundle/runtime'; +import type { CliRouteConfig, CliRouteProps } from 'agent-bundle'; +import { z } from 'zod'; + +import { + resultSchema, + resultText, + sendOperation, +} from '../../core/chatgpt-desktop/routes.js'; + +export const config = { + description: + 'EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.', + exitCode: 'result', + positionals: ['text'], + inputJsonSchema: { + additionalProperties: false, + properties: { + port: { type: 'number' }, + text: { type: 'array', items: { type: 'string' } }, + threadId: { type: 'string' }, + }, + required: ['text'], + type: 'object', + }, + render: { maxElapsedMs: 120000 }, +} satisfies CliRouteConfig; + +export const inputSchema = z + .object({ + port: z.number().int().min(1).max(65535).optional(), + text: z.array(z.string()).min(1), + threadId: z.string().min(1).max(256).optional(), + }) + .strict(); +export { resultSchema }; + +export default async function chatgptDesktopSend({ + input, +}: CliRouteProps) { + const out = await sendOperation({ + port: input.port, + threadId: input.threadId, + text: input.text.join(' ').trim(), + }); + return ( + + {resultText(out)} + + ); +} diff --git a/src/cli/chatgpt-desktop/status.tsx b/src/cli/chatgpt-desktop/status.tsx new file mode 100644 index 0000000..2d098e2 --- /dev/null +++ b/src/cli/chatgpt-desktop/status.tsx @@ -0,0 +1,40 @@ +import { Agent } from '@agent-bundle/runtime'; +import type { CliRouteConfig, CliRouteProps } from 'agent-bundle'; +import { z } from 'zod'; + +import { + resultSchema, + resultText, + statusOperation, +} from '../../core/chatgpt-desktop/routes.js'; + +export const config = { + description: + 'Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.', + exitCode: 'result', + inputJsonSchema: { + additionalProperties: false, + properties: { + port: { description: 'Local CDP port (default 9222)', type: 'number' }, + }, + type: 'object', + }, +} satisfies CliRouteConfig; + +export const inputSchema = z + .object({ + port: z.number().int().min(1).max(65535).optional(), + }) + .strict(); +export { resultSchema }; + +export default async function chatgptDesktopStatus({ + input, +}: CliRouteProps) { + const out = await statusOperation(input); + return ( + + {resultText(out)} + + ); +} diff --git a/src/cli/chatgpt-desktop/threads.tsx b/src/cli/chatgpt-desktop/threads.tsx new file mode 100644 index 0000000..5db6da5 --- /dev/null +++ b/src/cli/chatgpt-desktop/threads.tsx @@ -0,0 +1,59 @@ +import { Agent } from '@agent-bundle/runtime'; +import type { CliRouteConfig, CliRouteProps } from 'agent-bundle'; +import { z } from 'zod'; + +import { + listThreadsOperation, + resultSchema, + resultText, +} from '../../core/chatgpt-desktop/routes.js'; + +export const config = { + description: 'List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).', + exitCode: 'result', + inputJsonSchema: { + additionalProperties: false, + properties: { + limit: { default: 50, description: 'Max threads (1-200)', type: 'number' }, + port: { description: 'Local CDP port', type: 'number' }, + }, + type: 'object', + }, +} satisfies CliRouteConfig; + +export const inputSchema = z + .object({ + limit: z.number().int().min(1).max(200).default(50), + port: z.number().int().min(1).max(65535).optional(), + }) + .strict(); +export { resultSchema }; + +export default async function chatgptDesktopThreads({ + input, +}: CliRouteProps) { + const out = await listThreadsOperation(input); + const threads = Array.isArray(out.threads) ? out.threads : []; + const text = + threads.length > 0 + ? threads + .map((thread) => { + const row = thread as { + threadId?: string; + title?: string; + selected?: boolean; + pinned?: boolean; + }; + return ( + `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + + (row.pinned ? ' (pinned)' : '') + ); + }) + .join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` + : resultText(out); + return ( + + {text} + + ); +} diff --git a/src/core/chatgpt-desktop/adapter.ts b/src/core/chatgpt-desktop/adapter.ts new file mode 100644 index 0000000..285c8c6 --- /dev/null +++ b/src/core/chatgpt-desktop/adapter.ts @@ -0,0 +1,26 @@ +import type { + ChatGptDesktopStatus, + ChatGptDesktopTarget, + ListThreadsResult, + OpenThreadResult, + ReadThreadResult, + SendMessageResult, + WaitForReplyResult, +} from './types.js'; + +/** + * Stable surface for ChatGPT Desktop automation. CDP/DOM details stay behind + * the implementation; callers use these methods only. + */ +export interface ChatGptDesktopAdapter { + connect(options: { port: number }): Promise; + listTargets(): Promise; + listThreads(options?: { limit?: number }): Promise; + readThread(options: { threadId: string; limit?: number }): Promise; + /** Omitting `threadId` starts a new thread (composer in a new chat). */ + sendMessage(options: { threadId?: string; text: string }): Promise; + waitForReply(options: { threadId: string; timeoutMs?: number }): Promise; + openThread(threadId: string): Promise; + status(): Promise; + close(): Promise; +} diff --git a/src/core/chatgpt-desktop/app-server-fallback.ts b/src/core/chatgpt-desktop/app-server-fallback.ts new file mode 100644 index 0000000..e210087 --- /dev/null +++ b/src/core/chatgpt-desktop/app-server-fallback.ts @@ -0,0 +1,188 @@ +/** + * App-server fallback for ChatGPT Desktop operations that also exist on the + * managed Codex daemon. Reuses the existing codex-bridge client — does not + * duplicate the WebSocket/JSON-RPC stack. + */ + +import { + codexStatus, + listCodexThreads, + openCodexSession, + sendToCodexThread, +} from '../codex-bridge.js'; +import type { + ListThreadsResult, + OpenThreadResult, + ReadThreadResult, + SendMessageResult, + WaitForReplyResult, +} from './types.js'; + +export async function appServerListThreads({ + limit = 50, +}: { + limit?: number; +} = {}): Promise { + const out = await listCodexThreads({ limit }); + return { + backend: 'app-server', + limit: out.limit, + threads: out.threads.map((thread: { + id?: string; + name?: string; + preview?: string; + cwd?: string; + }) => ({ + threadId: String(thread.id ?? ''), + title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), + pinned: false, + selected: false, + kind: 'codex', + })), + }; +} + +export async function appServerReadThread({ + threadId, + limit = 100, +}: { + threadId: string; + limit?: number; +}): Promise { + const { client } = await openCodexSession(); + try { + // Prefer thread/read when the daemon supports it; fall back to items list. + let turns: ReadThreadResult['turns'] = []; + try { + const read = await client.request('thread/read', { threadId }) as { + thread?: { turns?: unknown[]; items?: unknown[] }; + turns?: unknown[]; + items?: unknown[]; + }; + const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; + turns = normalizeTurns(raw).slice(-limit); + } catch { + const items = await client.request('thread/items/list', { + threadId, + limit: Math.min(limit, 100), + }) as { data?: unknown[] }; + turns = normalizeTurns(items.data ?? []).slice(-limit); + } + return { threadId, turns, backend: 'app-server', limit }; + } finally { + client.close(); + } +} + +export async function appServerSendMessage({ + threadId, + text, +}: { + threadId?: string; + text: string; +}): Promise { + if (!threadId) { + return { + threadId: 'new', + backend: 'app-server', + experimental: false, + delivery: 'rejected', + message: + 'app-server fallback requires an existing threadId; starting a new Desktop thread needs CDP', + }; + } + const receipt = await sendToCodexThread(threadId, text); + return { + threadId, + backend: 'app-server', + experimental: false, + delivery: (receipt.delivery as SendMessageResult['delivery']) ?? 'accepted', + message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined, + }; +} + +export async function appServerWaitForReply({ + threadId, + timeoutMs = 60000, +}: { + threadId: string; + timeoutMs?: number; +}): Promise { + // Reuse the existing session client; poll thread/items/list for a fresh agent message. + const baseline = await appServerReadThread({ threadId, limit: 200 }); + const seen = new Set(baseline.turns.map((turn) => turn.turnKey)); + const deadline = Date.now() + timeoutMs; + while (Date.now() < deadline) { + await new Promise((resolve) => setTimeout(resolve, 400)); + const page = await appServerReadThread({ threadId, limit: 200 }); + const fresh = page.turns.filter((turn) => !seen.has(turn.turnKey) && turn.role === 'assistant' && turn.text); + const reply = fresh.at(-1)?.text ?? ''; + if (reply) { + return { + threadId, + reply, + backend: 'app-server', + experimental: false, + delivery: 'replied', + }; + } + } + return { + threadId, + reply: '', + backend: 'app-server', + experimental: false, + delivery: 'timeout', + }; +} + +export async function appServerOpenThread(threadId: string): Promise { + const { client } = await openCodexSession(); + try { + await client.request('thread/resume', { threadId, excludeTurns: true }); + return { threadId, backend: 'app-server' }; + } finally { + client.close(); + } +} + +export async function appServerStatusProbe(): Promise<{ + reachable: boolean; + mode?: string; + socketPath?: string; +}> { + const status = (await codexStatus()) as { + reachable?: boolean; + mode?: string; + socketPath?: string; + }; + return { + reachable: Boolean(status.reachable && status.mode === 'daemon'), + mode: typeof status.mode === 'string' ? status.mode : undefined, + socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined, + }; +} + +function normalizeTurns(raw: unknown[]): ReadThreadResult['turns'] { + const turns: Array = []; + for (const [index, item] of raw.entries()) { + if (!item || typeof item !== 'object') continue; + const row = item as Record; + const text = + typeof row.text === 'string' + ? row.text + : typeof row.content === 'string' + ? row.content + : ''; + const type = String(row.type ?? row.role ?? ''); + let role: 'user' | 'assistant' | 'status' = 'assistant'; + if (/user/i.test(type)) role = 'user'; + else if (/status|system|reasoning/i.test(type) && !text) role = 'status'; + turns.push({ + turnKey: String(row.id ?? row.turnId ?? index), + role, + text, + }); + } + return turns; +} diff --git a/src/core/chatgpt-desktop/cdp-adapter.ts b/src/core/chatgpt-desktop/cdp-adapter.ts new file mode 100644 index 0000000..3670a7b --- /dev/null +++ b/src/core/chatgpt-desktop/cdp-adapter.ts @@ -0,0 +1,251 @@ +import type { ChatGptDesktopAdapter } from './adapter.js'; +import { CdpUnreachableError } from './errors.js'; +import { CdpSession } from './cdp-session.js'; +import { + listThreadsFromDom, + openThreadInDom, + pickMainWindowTarget, + readTurnsFromDom, + sendMessageInDom, + summarizeTargetInfos, +} from './cdp-dom.js'; +import { resolveCdpPort } from './loopback.js'; +import type { + ChatGptDesktopStatus, + ChatGptDesktopTarget, + ListThreadsResult, + OpenThreadResult, + ReadThreadResult, + SendMessageResult, + WaitForReplyResult, +} from './types.js'; + +type TargetGetTargetsResult = { + targetInfos?: Array<{ + targetId?: string; + type?: string; + title?: string; + url?: string; + attached?: boolean; + }>; +}; + +/** + * CDP-backed ChatGPT Desktop adapter. Selector/data logic stays in cdp-dom.ts. + * Prefer Target.getTargets over /json/list (incomplete + unstable order). + */ +export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { + #port = resolveCdpPort(); + #session: CdpSession | null = null; + #version: Awaited> | null = null; + #pageSessionId: string | null = null; + #mainTargetId: string | null = null; + + async connect({ port }: { port: number }): Promise { + await this.close(); + this.#port = resolveCdpPort(process.env, port); + const session = new CdpSession(this.#port); + try { + this.#version = await session.connect(); + this.#session = session; + await this.#attachMainWindow(); + } catch (error) { + session.close(); + this.#session = null; + // Keep #port so status() can still probe /json/version on the same port. + throw error; + } + } + + async listTargets(): Promise { + const session = this.#requireSession(); + // Target.getTargets is authoritative; /json/list is incomplete and order-unstable. + const result = await session.send('Target.getTargets'); + return summarizeTargetInfos(result.targetInfos ?? []); + } + + async listThreads({ limit = 50 }: { limit?: number } = {}): Promise { + const sessionId = await this.#ensurePageSession(); + const threads = await listThreadsFromDom(this.#requireSession(), sessionId, { limit }); + return { threads, backend: 'cdp', limit }; + } + + async readThread({ + threadId, + limit = 100, + }: { + threadId: string; + limit?: number; + }): Promise { + const sessionId = await this.#ensurePageSession(); + await openThreadInDom(this.#requireSession(), sessionId, threadId); + // Allow the virtualized timeline to settle after the click. + await delay(150); + const turns = await readTurnsFromDom(this.#requireSession(), sessionId, { limit }); + return { threadId, turns, backend: 'cdp', limit }; + } + + async sendMessage({ + threadId, + text, + }: { + threadId?: string; + text: string; + }): Promise { + const sessionId = await this.#ensurePageSession(); + if (threadId) { + await openThreadInDom(this.#requireSession(), sessionId, threadId); + await delay(100); + } + await sendMessageInDom(this.#requireSession(), sessionId, text); + return { + threadId: threadId ?? 'new', + backend: 'cdp', + experimental: true, + delivery: 'accepted', + message: 'Submitted via experimental CDP composer path', + }; + } + + async waitForReply({ + threadId, + timeoutMs = 60000, + }: { + threadId: string; + timeoutMs?: number; + }): Promise { + const sessionId = await this.#ensurePageSession(); + await openThreadInDom(this.#requireSession(), sessionId, threadId); + const deadline = Date.now() + timeoutMs; + let previousKeys = new Set(); + let lastAssistant = ''; + let stable = 0; + + // Baseline existing turns so we wait for a *new* assistant turn. + const baseline = await readTurnsFromDom(this.#requireSession(), sessionId, { limit: 500 }); + previousKeys = new Set(baseline.map((t) => t.turnKey)); + + while (Date.now() < deadline) { + await delay(400); + const turns = await readTurnsFromDom(this.#requireSession(), sessionId, { limit: 500 }); + const fresh = turns.filter((t) => !previousKeys.has(t.turnKey) && t.role === 'assistant'); + const candidate = fresh.at(-1)?.text ?? ''; + if (candidate && candidate === lastAssistant) { + stable += 1; + if (stable >= 3) { + return { + threadId, + reply: candidate, + backend: 'cdp', + experimental: true, + delivery: 'replied', + }; + } + } else if (candidate) { + lastAssistant = candidate; + stable = 0; + } + } + return { + threadId, + reply: lastAssistant, + backend: 'cdp', + experimental: true, + delivery: lastAssistant ? 'replied' : 'timeout', + }; + } + + async openThread(threadId: string): Promise { + const sessionId = await this.#ensurePageSession(); + await openThreadInDom(this.#requireSession(), sessionId, threadId); + return { threadId, backend: 'cdp' }; + } + + async status(): Promise { + try { + const version = this.#version ?? (await CdpSession.fetchVersion(this.#port)); + let targetCount: number | undefined; + let mainWindowTargetId: string | null | undefined; + if (this.#session && !this.#session.closed) { + const targets = await this.listTargets(); + targetCount = targets.length; + mainWindowTargetId = pickMainWindowTarget(targets)?.targetId ?? null; + } else { + // Cheap probe without attaching: /json/list is incomplete but fine for a count hint. + const list = await CdpSession.fetchJsonList(this.#port); + targetCount = list.length; + } + return { + reachable: true, + port: this.#port, + host: '127.0.0.1', + browser: typeof version.Browser === 'string' ? version.Browser : undefined, + protocolVersion: + typeof version['Protocol-Version'] === 'string' ? version['Protocol-Version'] : undefined, + webSocketDebuggerUrl: + typeof version.webSocketDebuggerUrl === 'string' ? version.webSocketDebuggerUrl : undefined, + targetCount, + mainWindowTargetId: mainWindowTargetId ?? this.#mainTargetId, + message: 'ChatGPT Desktop CDP endpoint reachable on 127.0.0.1', + exitCode: 0, + }; + } catch (error) { + return { + reachable: false, + port: this.#port, + host: '127.0.0.1', + message: + error instanceof Error + ? error.message + : 'ChatGPT Desktop CDP endpoint unreachable on 127.0.0.1', + exitCode: 1, + }; + } + } + + async close(): Promise { + this.#pageSessionId = null; + this.#mainTargetId = null; + this.#version = null; + this.#session?.close(); + this.#session = null; + } + + async #attachMainWindow(): Promise { + const targets = await this.listTargets(); + const main = pickMainWindowTarget(targets); + if (!main) { + throw new CdpUnreachableError( + `No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`, + ); + } + const attached = await this.#requireSession().send<{ sessionId: string }>( + 'Target.attachToTarget', + { targetId: main.targetId, flatten: true }, + ); + this.#mainTargetId = main.targetId; + this.#pageSessionId = attached.sessionId; + } + + async #ensurePageSession(): Promise { + this.#requireSession(); + if (!this.#pageSessionId) await this.#attachMainWindow(); + if (!this.#pageSessionId) { + throw new CdpUnreachableError('Failed to attach to ChatGPT Desktop main window'); + } + return this.#pageSessionId; + } + + #requireSession(): CdpSession { + if (!this.#session || this.#session.closed) { + throw new CdpUnreachableError( + 'Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.', + ); + } + return this.#session; + } +} + +function delay(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/src/core/chatgpt-desktop/cdp-dom.ts b/src/core/chatgpt-desktop/cdp-dom.ts new file mode 100644 index 0000000..59a06a6 --- /dev/null +++ b/src/core/chatgpt-desktop/cdp-dom.ts @@ -0,0 +1,275 @@ +/** + * ChatGPT Desktop DOM / data-layer for CDP Runtime.evaluate. + * + * ALL selector and in-page data extraction lives in this module. The adapter + * and tools must not invent additional DOM selectors. + * + * Evidence (macOS ChatGPT.app / Codex Desktop, Electron, Chrome 154, + * bundle com.openai.codex, v26.924.22138): + * - Main window URL is exactly `app://-/index.html` (no query). + * - Sidebar rows: `[role=button][data-app-action-sidebar-thread-row]` with + * `data-app-action-sidebar-thread-{id,title,pinned,selected,kind}`. + * - Thread surface is the second `
` (`_MainContentSurface…`). + * - Turns: `[data-turn-key]`; user bubbles: `[data-user-message-bubble]`. + * - Timeline scroll: `[data-app-action-timeline-scroll]` (virtualized). + * - send/waitForReply composer path is experimental (not fully explored). + */ + +import type { ChatGptDesktopTarget, ChatGptDesktopThread, ChatGptDesktopTurn } from './types.js'; +import type { CdpSession } from './cdp-session.js'; + +/** Exact main-window URL; ignore avatar-overlay, detached-window, webviews. */ +export const MAIN_WINDOW_URL = 'app://-/index.html'; + +export const ATTR = { + threadRow: 'data-app-action-sidebar-thread-row', + threadId: 'data-app-action-sidebar-thread-id', + threadTitle: 'data-app-action-sidebar-thread-title', + threadPinned: 'data-app-action-sidebar-thread-pinned', + threadSelected: 'data-app-action-sidebar-thread-selected', + threadKind: 'data-app-action-sidebar-thread-kind', + turnKey: 'data-turn-key', + userBubble: 'data-user-message-bubble', + timelineScroll: 'data-app-action-timeline-scroll', + virtualizedTurn: 'data-virtualized-turn-content', +} as const; + +export const SELECTORS = { + threadRow: `[role="button"][${ATTR.threadRow}]`, + turn: `[${ATTR.turnKey}]`, + userBubble: `[${ATTR.userBubble}]`, + timelineScroll: `[${ATTR.timelineScroll}]`, + mainSurface: 'main', + /** + * Experimental composer candidates (send/waitForReply not fully explored). + * Prefer a contenteditable / textarea inside the main surface. + */ + composerCandidates: [ + 'main [contenteditable="true"]', + 'main textarea', + '[data-app-action-composer] [contenteditable="true"]', + '[data-app-action-composer] textarea', + 'form [contenteditable="true"]', + 'form textarea', + ], + sendButtonCandidates: [ + 'button[data-app-action-send]', + 'button[aria-label="Send"]', + 'button[aria-label="Send message"]', + 'main button[type="submit"]', + ], +} as const; + +export function isMainWindowTarget(target: { + type?: string; + url?: string; +}): boolean { + return target.type === 'page' && target.url === MAIN_WINDOW_URL; +} + +export function summarizeTargetInfos( + targetInfos: readonly { + targetId?: string; + type?: string; + title?: string; + url?: string; + attached?: boolean; + }[], +): ChatGptDesktopTarget[] { + return targetInfos + .filter((t) => typeof t.targetId === 'string' && typeof t.type === 'string') + .map((t) => ({ + targetId: String(t.targetId), + type: String(t.type), + title: typeof t.title === 'string' ? t.title : '', + url: typeof t.url === 'string' ? t.url : '', + attached: Boolean(t.attached), + })); +} + +export function pickMainWindowTarget( + targets: readonly ChatGptDesktopTarget[], +): ChatGptDesktopTarget | null { + return targets.find((t) => isMainWindowTarget(t)) ?? null; +} + +/** In-page script: list sidebar threads from data attributes. */ +export const LIST_THREADS_EXPRESSION = `(() => { + const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); + return rows.map((row) => ({ + threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || '', + title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), + pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', + selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', + kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + })).filter((t) => t.threadId); +})()`; + +/** In-page script: click a sidebar row by thread id (URL does not change). */ +export function openThreadExpression(threadId: string): string { + return `(() => { + const id = ${JSON.stringify(threadId)}; + const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); + const row = rows.find((el) => el.getAttribute(${JSON.stringify(ATTR.threadId)}) === id); + if (!row) return { ok: false, error: 'thread-not-found' }; + row.click(); + return { ok: true, threadId: id }; + })()`; +} + +/** + * Scroll the virtualized timeline and collect turns keyed by data-turn-key. + * User turns contain [data-user-message-bubble]; other turns are assistant/status. + * Voice turns that only show "Worked for Xs" become status. + */ +export const READ_THREAD_EXPRESSION = `(() => { + const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + const mains = Array.from(document.querySelectorAll('main')); + const surface = mains.length >= 2 ? mains[1] : (mains[0] || document.body); + const root = scroll || surface; + const collected = new Map(); + const statusRe = /^Worked for \\d+s$/i; + const harvest = () => { + for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { + const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; + if (!turnKey || collected.has(turnKey)) continue; + const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); + const text = (el.innerText || '').trim(); + let role = 'assistant'; + if (user) role = 'user'; + else if (!text || statusRe.test(text)) role = 'status'; + collected.set(turnKey, { turnKey, role, text }); + } + }; + const maxPasses = 80; + let stable = 0; + let lastSize = -1; + if (scroll) scroll.scrollTop = 0; + for (let i = 0; i < maxPasses; i++) { + harvest(); + if (collected.size === lastSize) { + stable += 1; + if (stable >= 3) break; + } else { + stable = 0; + lastSize = collected.size; + } + if (scroll) { + const next = Math.min(scroll.scrollHeight, scroll.scrollTop + Math.max(scroll.clientHeight, 200)); + if (next <= scroll.scrollTop && stable >= 1) break; + scroll.scrollTop = next; + } else { + break; + } + } + harvest(); + return Array.from(collected.values()); +})()`; + +/** Experimental: insert text into the composer and submit (Enter / send button). */ +export function sendMessageExpression(text: string): string { + const composers = JSON.stringify([...SELECTORS.composerCandidates]); + const buttons = JSON.stringify([...SELECTORS.sendButtonCandidates]); + return `(() => { + const text = ${JSON.stringify(text)}; + const composers = ${composers}; + let composer = null; + for (const sel of composers) { + composer = document.querySelector(sel); + if (composer) break; + } + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.focus(); + if (composer.isContentEditable) { + composer.textContent = text; + composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: text, inputType: 'insertText' })); + } else if ('value' in composer) { + composer.value = text; + composer.dispatchEvent(new Event('input', { bubbles: true })); + } else { + return { ok: false, error: 'composer-unsupported' }; + } + const buttons = ${buttons}; + let sent = false; + for (const sel of buttons) { + const btn = document.querySelector(sel); + if (btn && !btn.disabled) { btn.click(); sent = true; break; } + } + if (!sent) { + composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true })); + composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', bubbles: true })); + } + return { ok: true, sentVia: sent ? 'button' : 'enter' }; + })()`; +} + +export async function listThreadsFromDom( + session: CdpSession, + sessionId: string, + { limit = 50 }: { limit?: number } = {}, +): Promise { + const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { sessionId }); + if (!Array.isArray(rows)) return []; + return rows.slice(0, limit).map((row) => ({ + threadId: String(row.threadId), + title: String(row.title ?? ''), + pinned: Boolean(row.pinned), + selected: Boolean(row.selected), + kind: String(row.kind ?? 'unknown'), + })); +} + +export async function openThreadInDom( + session: CdpSession, + sessionId: string, + threadId: string, +): Promise { + const result = await session.evaluate<{ ok: boolean; error?: string }>( + openThreadExpression(threadId), + { sessionId }, + ); + if (!result?.ok) { + throw new Error(result?.error === 'thread-not-found' + ? `ChatGPT Desktop thread not found: ${threadId}` + : `Failed to open ChatGPT Desktop thread ${threadId}`); + } +} + +export async function readTurnsFromDom( + session: CdpSession, + sessionId: string, + { limit = 100 }: { limit?: number } = {}, +): Promise { + const turns = await session.evaluate(READ_THREAD_EXPRESSION, { sessionId }); + if (!Array.isArray(turns)) return []; + return turns.slice(-limit).map((turn) => ({ + turnKey: String(turn.turnKey), + role: turn.role === 'user' || turn.role === 'status' ? turn.role : 'assistant', + text: String(turn.text ?? ''), + })); +} + +export async function sendMessageInDom( + session: CdpSession, + sessionId: string, + text: string, +): Promise<{ sentVia: string }> { + // Prefer CDP Input.insertText when focused; fall back to DOM script. + try { + await session.send('Input.insertText', { text }, { sessionId }); + } catch { + // Composer may not be focused yet; the evaluate path focuses + fills. + } + const result = await session.evaluate<{ ok: boolean; error?: string; sentVia?: string }>( + sendMessageExpression(text), + { sessionId }, + ); + if (!result?.ok) { + throw new Error( + result?.error === 'composer-not-found' + ? 'ChatGPT Desktop composer not found (experimental send path)' + : `ChatGPT Desktop send failed: ${result?.error ?? 'unknown'}`, + ); + } + return { sentVia: result.sentVia ?? 'unknown' }; +} diff --git a/src/core/chatgpt-desktop/cdp-session.ts b/src/core/chatgpt-desktop/cdp-session.ts new file mode 100644 index 0000000..2485603 --- /dev/null +++ b/src/core/chatgpt-desktop/cdp-session.ts @@ -0,0 +1,190 @@ +import { CdpUnreachableError } from './errors.js'; +import { + assertLoopbackHostname, + cdpHttpBase, + forceLoopbackWebSocketUrl, +} from './loopback.js'; + +export type CdpVersionInfo = { + readonly Browser?: string; + readonly 'Protocol-Version'?: string; + readonly webSocketDebuggerUrl?: string; + readonly [key: string]: unknown; +}; + +type Pending = { + resolve: (value: unknown) => void; + reject: (error: Error) => void; +}; + +/** + * Minimal local-only CDP client. Connects to 127.0.0.1 only; never accepts a + * remote host. Uses Node's built-in WebSocket (no extra dependency). + */ +export class CdpSession { + #port: number; + #ws: WebSocket | null = null; + #nextId = 1; + #pending = new Map(); + #closed = false; + + constructor(port: number) { + this.#port = port; + } + + get port(): number { + return this.#port; + } + + get closed(): boolean { + return this.#closed || this.#ws === null || this.#ws.readyState === WebSocket.CLOSED; + } + + static async fetchVersion(port: number, { signal }: { signal?: AbortSignal } = {}): Promise { + const base = cdpHttpBase(port); + let response: Response; + try { + response = await fetch(`${base}/json/version`, { signal }); + } catch (error) { + throw new CdpUnreachableError( + `ChatGPT Desktop CDP not reachable at ${base}/json/version: ` + + (error instanceof Error ? error.message : String(error)), + ); + } + if (!response.ok) { + throw new CdpUnreachableError( + `ChatGPT Desktop CDP /json/version returned HTTP ${response.status}`, + ); + } + return (await response.json()) as CdpVersionInfo; + } + + static async fetchJsonList(port: number, { signal }: { signal?: AbortSignal } = {}): Promise { + const base = cdpHttpBase(port); + let response: Response; + try { + response = await fetch(`${base}/json/list`, { signal }); + } catch (error) { + throw new CdpUnreachableError( + `ChatGPT Desktop CDP not reachable at ${base}/json/list: ` + + (error instanceof Error ? error.message : String(error)), + ); + } + if (!response.ok) { + throw new CdpUnreachableError( + `ChatGPT Desktop CDP /json/list returned HTTP ${response.status}`, + ); + } + const body: unknown = await response.json(); + return Array.isArray(body) ? body : []; + } + + async connect({ signal }: { signal?: AbortSignal } = {}): Promise { + if (this.#ws && !this.closed) { + throw new Error('CDP session already connected'); + } + const version = await CdpSession.fetchVersion(this.#port, { signal }); + const rawUrl = version.webSocketDebuggerUrl; + if (typeof rawUrl !== 'string' || !rawUrl) { + throw new CdpUnreachableError('CDP /json/version omitted webSocketDebuggerUrl'); + } + const url = forceLoopbackWebSocketUrl(rawUrl); + const parsed = new URL(url); + assertLoopbackHostname(parsed.hostname); + + await new Promise((resolve, reject) => { + const ws = new WebSocket(url); + this.#ws = ws; + const onAbort = () => { + ws.close(); + reject(new Error('CDP connect aborted')); + }; + signal?.addEventListener('abort', onAbort, { once: true }); + ws.addEventListener('open', () => { + signal?.removeEventListener('abort', onAbort); + resolve(); + }, { once: true }); + ws.addEventListener('error', () => { + signal?.removeEventListener('abort', onAbort); + reject(new CdpUnreachableError(`CDP WebSocket failed for ${url}`)); + }, { once: true }); + ws.addEventListener('message', (event) => this.#onMessage(event.data)); + ws.addEventListener('close', () => { + this.#closed = true; + for (const [, pending] of this.#pending) { + pending.reject(new Error('CDP WebSocket closed')); + } + this.#pending.clear(); + }); + }); + this.#closed = false; + return version; + } + + async send( + method: string, + params?: Record, + { sessionId }: { sessionId?: string } = {}, + ): Promise { + if (!this.#ws || this.#ws.readyState !== WebSocket.OPEN) { + throw new CdpUnreachableError('CDP session is not connected'); + } + const id = this.#nextId++; + const payload: Record = { id, method }; + if (params !== undefined) payload.params = params; + if (sessionId !== undefined) payload.sessionId = sessionId; + return await new Promise((resolve, reject) => { + this.#pending.set(id, { + resolve: (value) => resolve(value as T), + reject, + }); + this.#ws!.send(JSON.stringify(payload)); + }); + } + + async evaluate( + expression: string, + { sessionId, awaitPromise = true }: { sessionId?: string; awaitPromise?: boolean } = {}, + ): Promise { + const result = await this.send<{ + result?: { type?: string; value?: unknown; description?: string }; + exceptionDetails?: { text?: string; exception?: { description?: string } }; + }>('Runtime.evaluate', { + expression, + returnByValue: true, + awaitPromise, + }, { sessionId }); + if (result.exceptionDetails) { + const text = + result.exceptionDetails.exception?.description || + result.exceptionDetails.text || + 'Runtime.evaluate failed'; + throw new Error(text); + } + return result.result?.value as T; + } + + close(): void { + this.#closed = true; + this.#ws?.close(); + this.#ws = null; + } + + #onMessage(data: unknown): void { + let message: { id?: number; result?: unknown; error?: { message?: string } }; + try { + message = JSON.parse(String(data)) as typeof message; + } catch { + return; + } + if (typeof message.id !== 'number') return; + const pending = this.#pending.get(message.id); + if (!pending) return; + this.#pending.delete(message.id); + if (message.error) { + pending.reject(new Error(message.error.message || 'CDP error')); + return; + } + pending.resolve(message.result); + } +} diff --git a/src/core/chatgpt-desktop/errors.ts b/src/core/chatgpt-desktop/errors.ts new file mode 100644 index 0000000..55b625a --- /dev/null +++ b/src/core/chatgpt-desktop/errors.ts @@ -0,0 +1,42 @@ +/** Typed failure when a ChatGPT Desktop CDP/DOM operation is not yet implemented. */ +export class NotImplementedError extends Error { + readonly code = 'NOT_IMPLEMENTED' as const; + readonly delivery = 'rejected' as const; + readonly reason = 'not-implemented' as const; + + constructor(operation: string, detail?: string) { + super( + detail + ? `ChatGPT Desktop ${operation} is not implemented: ${detail}` + : `ChatGPT Desktop ${operation} is not implemented`, + ); + this.name = 'NotImplementedError'; + } +} + +/** Thrown when a CDP endpoint host is not loopback. */ +export class CdpHostRejectedError extends Error { + readonly code = 'CDP_HOST_REJECTED' as const; + readonly delivery = 'rejected' as const; + readonly reason = 'cdp-host-rejected' as const; + + constructor(host: string) { + super( + `ChatGPT Desktop CDP rejects non-loopback host ${JSON.stringify(host)}. ` + + 'Connect to 127.0.0.1 only; there is no remote transport.', + ); + this.name = 'CdpHostRejectedError'; + } +} + +/** Thrown when the local CDP endpoint is unreachable. */ +export class CdpUnreachableError extends Error { + readonly code = 'CDP_UNREACHABLE' as const; + readonly delivery = 'rejected' as const; + readonly reason = 'cdp-unreachable' as const; + + constructor(message: string) { + super(message); + this.name = 'CdpUnreachableError'; + } +} diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts new file mode 100644 index 0000000..b451a9e --- /dev/null +++ b/src/core/chatgpt-desktop/facade.ts @@ -0,0 +1,162 @@ +import type { ChatGptDesktopAdapter } from './adapter.js'; +import { CdpChatGptDesktopAdapter } from './cdp-adapter.js'; +import { + appServerListThreads, + appServerOpenThread, + appServerReadThread, + appServerSendMessage, + appServerStatusProbe, + appServerWaitForReply, +} from './app-server-fallback.js'; +import { CdpUnreachableError, NotImplementedError } from './errors.js'; +import { resolveCdpPort } from './loopback.js'; +import type { + ChatGptDesktopStatus, + ChatGptDesktopTarget, + ListThreadsResult, + OpenThreadResult, + ReadThreadResult, + SendMessageResult, + WaitForReplyResult, +} from './types.js'; + +/** + * Prefer CDP for ChatGPT Desktop; fall back to the existing Codex app-server + * client when CDP is unreachable for operations that app-server can serve. + * Every result reports `backend: "cdp" | "app-server"`. + */ +export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { + #cdp: ChatGptDesktopAdapter; + #port: number; + #cdpConnected = false; + + constructor(cdp: ChatGptDesktopAdapter = new CdpChatGptDesktopAdapter(), port = resolveCdpPort()) { + this.#cdp = cdp; + this.#port = port; + } + + async connect({ port }: { port: number }): Promise { + this.#port = resolveCdpPort(process.env, port); + try { + await this.#cdp.connect({ port: this.#port }); + this.#cdpConnected = true; + } catch (error) { + this.#cdpConnected = false; + throw error; + } + } + + async listTargets(): Promise { + await this.#ensureCdp(); + return this.#cdp.listTargets(); + } + + async listThreads(options?: { limit?: number }): Promise { + try { + await this.#ensureCdp(); + return await this.#cdp.listThreads(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return appServerListThreads(options); + } + } + + async readThread(options: { threadId: string; limit?: number }): Promise { + try { + await this.#ensureCdp(); + return await this.#cdp.readThread(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return appServerReadThread(options); + } + } + + async sendMessage(options: { threadId?: string; text: string }): Promise { + try { + await this.#ensureCdp(); + return await this.#cdp.sendMessage(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return appServerSendMessage(options); + } + } + + async waitForReply(options: { + threadId: string; + timeoutMs?: number; + }): Promise { + try { + await this.#ensureCdp(); + return await this.#cdp.waitForReply(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return appServerWaitForReply(options); + } + } + + async openThread(threadId: string): Promise { + try { + await this.#ensureCdp(); + return await this.#cdp.openThread(threadId); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return appServerOpenThread(threadId); + } + } + + async status(): Promise { + const cdpStatus = await this.#cdp.status(); + let appServerFallback: ChatGptDesktopStatus['appServerFallback']; + try { + appServerFallback = await appServerStatusProbe(); + } catch { + appServerFallback = { reachable: false }; + } + const reachable = cdpStatus.reachable || Boolean(appServerFallback?.reachable); + return { + ...cdpStatus, + port: this.#port, + appServerFallback, + reachable, + message: cdpStatus.reachable + ? cdpStatus.message + : appServerFallback?.reachable + ? 'CDP unreachable; Codex app-server fallback is available' + : cdpStatus.message, + exitCode: reachable ? 0 : 1, + }; + } + + async close(): Promise { + this.#cdpConnected = false; + await this.#cdp.close(); + } + + async #ensureCdp(): Promise { + if (this.#cdpConnected) return; + await this.#cdp.connect({ port: this.#port }); + this.#cdpConnected = true; + } +} + +function isCdpFailure(error: unknown): boolean { + if (error instanceof CdpUnreachableError) return true; + if (error instanceof NotImplementedError) return false; + if (error && typeof error === 'object' && 'code' in error) { + const code = String((error as { code: unknown }).code); + return code === 'CDP_UNREACHABLE' || code === 'CDP_HOST_REJECTED'; + } + return false; +} + +let activeAdapter: ChatGptDesktopAdapter | null = null; + +export function getChatGptDesktopAdapter(): ChatGptDesktopAdapter { + if (!activeAdapter) activeAdapter = new ChatGptDesktopFacade(); + return activeAdapter; +} + +/** Test hook: inject a fake adapter (or null to restore the default facade). */ +export function setChatGptDesktopAdapterForTests(adapter: ChatGptDesktopAdapter | null): void { + activeAdapter = adapter; +} diff --git a/src/core/chatgpt-desktop/index.ts b/src/core/chatgpt-desktop/index.ts new file mode 100644 index 0000000..30fc08b --- /dev/null +++ b/src/core/chatgpt-desktop/index.ts @@ -0,0 +1,63 @@ +export type { ChatGptDesktopAdapter } from './adapter.js'; +export { CdpChatGptDesktopAdapter } from './cdp-adapter.js'; +export { + ATTR, + MAIN_WINDOW_URL, + SELECTORS, + isMainWindowTarget, + pickMainWindowTarget, + summarizeTargetInfos, +} from './cdp-dom.js'; +export { CdpSession } from './cdp-session.js'; +export { + CdpHostRejectedError, + CdpUnreachableError, + NotImplementedError, +} from './errors.js'; +export { + ChatGptDesktopFacade, + getChatGptDesktopAdapter, + setChatGptDesktopAdapterForTests, +} from './facade.js'; +export { + CDP_LOOPBACK_HOST, + DEFAULT_CDP_PORT, + assertLoopbackHostname, + cdpHttpBase, + forceLoopbackWebSocketUrl, + isLoopbackHostname, + resolveCdpPort, +} from './loopback.js'; +export { + CHATGPT_APP_PATH, + CHATGPT_BUNDLE_ID, + chatgptDesktopRelaunchArgs, + chatgptDesktopRelaunchCommand, + relaunchChatGptDesktopWithCdp, +} from './relaunch.js'; +export { + listThreadsOperation, + listThreadsSchema, + readThreadOperation, + readThreadSchema, + resultSchema, + resultText, + sendOperation, + sendSchema, + statusOperation, + statusSchema, + waitReplyOperation, + waitReplySchema, +} from './routes.js'; +export type { + ChatGptDesktopBackend, + ChatGptDesktopStatus, + ChatGptDesktopTarget, + ChatGptDesktopThread, + ChatGptDesktopTurn, + ListThreadsResult, + OpenThreadResult, + ReadThreadResult, + SendMessageResult, + WaitForReplyResult, +} from './types.js'; diff --git a/src/core/chatgpt-desktop/loopback.ts b/src/core/chatgpt-desktop/loopback.ts new file mode 100644 index 0000000..e90708e --- /dev/null +++ b/src/core/chatgpt-desktop/loopback.ts @@ -0,0 +1,64 @@ +import { CdpHostRejectedError } from './errors.js'; + +const LOOPBACK = new Set(['127.0.0.1', 'localhost', '::1']); + +export const DEFAULT_CDP_PORT = 9222; +export const CDP_LOOPBACK_HOST = '127.0.0.1' as const; + +export function isLoopbackHostname(hostname: string): boolean { + const host = String(hostname || '') + .toLowerCase() + .replace(/^\[|\]$/g, ''); + return LOOPBACK.has(host); +} + +/** Reject any non-loopback host. CDP stays local-only with no remote transport. */ +export function assertLoopbackHostname(hostname: string): void { + if (!isLoopbackHostname(hostname)) { + throw new CdpHostRejectedError(hostname); + } +} + +/** + * Build the HTTP base URL for the Chromium debug port. + * Always dials 127.0.0.1 — never a caller-supplied host. + */ +export function cdpHttpBase(port: number): string { + if (!Number.isInteger(port) || port < 1 || port > 65535) { + throw new RangeError('CDP port must be an integer 1-65535'); + } + return `http://${CDP_LOOPBACK_HOST}:${port}`; +} + +/** Rewrite a debugger WebSocket URL so the host is forced to 127.0.0.1. */ +export function forceLoopbackWebSocketUrl(raw: string): string { + let url: URL; + try { + url = new URL(raw); + } catch { + throw new CdpHostRejectedError(String(raw)); + } + assertLoopbackHostname(url.hostname); + if (url.protocol !== 'ws:' && url.protocol !== 'wss:') { + throw new Error(`Expected ws(s) debugger URL, got ${url.protocol}`); + } + url.hostname = CDP_LOOPBACK_HOST; + url.protocol = 'ws:'; + return url.toString(); +} + +export function resolveCdpPort(env: NodeJS.ProcessEnv = process.env, explicit?: number): number { + if (explicit !== undefined) { + if (!Number.isInteger(explicit) || explicit < 1 || explicit > 65535) { + throw new RangeError('CDP port must be an integer 1-65535'); + } + return explicit; + } + const raw = (env.CHATGPT_DESKTOP_CDP_PORT || '').trim(); + if (!raw) return DEFAULT_CDP_PORT; + const port = Number.parseInt(raw, 10); + if (!Number.isInteger(port) || port < 1 || port > 65535) { + throw new RangeError('CHATGPT_DESKTOP_CDP_PORT must be an integer 1-65535'); + } + return port; +} diff --git a/src/core/chatgpt-desktop/relaunch.ts b/src/core/chatgpt-desktop/relaunch.ts new file mode 100644 index 0000000..00b7e24 --- /dev/null +++ b/src/core/chatgpt-desktop/relaunch.ts @@ -0,0 +1,75 @@ +import { spawnSync } from 'node:child_process'; + +import { DEFAULT_CDP_PORT, resolveCdpPort } from './loopback.js'; + +export const CHATGPT_APP_PATH = '/Applications/ChatGPT.app'; +export const CHATGPT_BUNDLE_ID = 'com.openai.codex'; + +/** + * Shell command that quits ChatGPT Desktop and relaunches it with a local + * Chromium `--remote-debugging-port`. The Electron fuses block Node inspect / + * RunAsNode, but not this Chromium flag. The port binds to 127.0.0.1 only. + */ +export function chatgptDesktopRelaunchCommand({ + port = DEFAULT_CDP_PORT, + appPath = CHATGPT_APP_PATH, +}: { + port?: number; + appPath?: string; +} = {}): string { + const resolved = resolveCdpPort(process.env, port); + // Prefer `open -a` with --args so the debug port is on Chromium's argv. + return [ + `osascript -e 'tell application "ChatGPT" to quit'`, + `open -a ${shellQuote(appPath)} --args --remote-debugging-port=${resolved}`, + ].join(' && '); +} + +export function chatgptDesktopRelaunchArgs(port = DEFAULT_CDP_PORT): string[] { + return ['--remote-debugging-port=' + resolveCdpPort(process.env, port)]; +} + +/** + * Best-effort macOS relaunch. Returns the command that was (or would be) run. + * Non-darwin platforms return `{ ran: false }` with the command for operators. + */ +export function relaunchChatGptDesktopWithCdp({ + port = DEFAULT_CDP_PORT, + appPath = CHATGPT_APP_PATH, + dryRun = false, + runner = spawnSync, +}: { + port?: number; + appPath?: string; + dryRun?: boolean; + runner?: typeof spawnSync; +} = {}): { + command: string; + ran: boolean; + platform: string; + port: number; + stdout?: string; + stderr?: string; + status?: number | null; +} { + const resolved = resolveCdpPort(process.env, port); + const command = chatgptDesktopRelaunchCommand({ port: resolved, appPath }); + if (dryRun || process.platform !== 'darwin') { + return { command, ran: false, platform: process.platform, port: resolved }; + } + const result = runner('bash', ['-lc', command], { encoding: 'utf8' }); + return { + command, + ran: true, + platform: process.platform, + port: resolved, + stdout: result.stdout || '', + stderr: result.stderr || '', + status: result.status, + }; +} + +function shellQuote(value: string): string { + if (/^[A-Za-z0-9_./:-]+$/.test(value)) return value; + return `'${value.replace(/'/g, `'\\''`)}'`; +} diff --git a/src/core/chatgpt-desktop/routes.ts b/src/core/chatgpt-desktop/routes.ts new file mode 100644 index 0000000..3628b84 --- /dev/null +++ b/src/core/chatgpt-desktop/routes.ts @@ -0,0 +1,178 @@ +import { z } from 'zod'; + +import { outcomeFromError } from '../codex/contract.js'; +import { NotImplementedError } from './errors.js'; +import { getChatGptDesktopAdapter } from './facade.js'; +import { resolveCdpPort } from './loopback.js'; + +const threadId = z.string().min(1).max(256); + +export const statusSchema = z + .object({ + port: z.number().int().min(1).max(65535).optional(), + }) + .strict(); + +export const listThreadsSchema = z + .object({ + port: z.number().int().min(1).max(65535).optional(), + limit: z.number().int().min(1).max(200).default(50), + }) + .strict(); + +export const readThreadSchema = z + .object({ + port: z.number().int().min(1).max(65535).optional(), + threadId, + limit: z.number().int().min(1).max(500).default(100), + }) + .strict(); + +export const sendSchema = z + .object({ + port: z.number().int().min(1).max(65535).optional(), + threadId: threadId.optional(), + text: z.string().min(1).max(100_000), + }) + .strict(); + +export const waitReplySchema = z + .object({ + port: z.number().int().min(1).max(65535).optional(), + threadId, + timeoutMs: z.number().int().min(1).max(600_000).default(60_000), + }) + .strict(); + +export const resultSchema = z + .object({ + exitCode: z.union([z.literal(0), z.literal(1)]), + }) + .catchall(z.json()); + +export type OperationResult = z.infer; + +async function withAdapter( + port: number | undefined, + run: (adapter: ReturnType) => Promise, +): Promise { + const adapter = getChatGptDesktopAdapter(); + const resolved = resolveCdpPort(process.env, port); + try { + await adapter.connect({ port: resolved }); + } catch { + // status/list may still succeed via HTTP probe or app-server fallback. + } + return run(adapter); +} + +function asResult(value: object): OperationResult { + return resultSchema.parse(value); +} + +function mapError(error: unknown): OperationResult { + if (error instanceof NotImplementedError) { + return asResult({ + delivery: 'rejected', + reason: 'not-implemented', + code: 'NOT_IMPLEMENTED', + error: error.message, + exitCode: 1 as const, + }); + } + const base = outcomeFromError(error); + if (error && typeof error === 'object' && 'code' in error) { + return asResult({ ...base, code: String((error as { code: unknown }).code) }); + } + return asResult(base); +} + +export async function statusOperation(input: z.infer): Promise { + try { + const status = await withAdapter(input.port, (adapter) => adapter.status()); + return asResult(status); + } catch (error) { + return mapError(error); + } +} + +export async function listThreadsOperation( + input: z.infer, +): Promise { + try { + const out = await withAdapter(input.port, (adapter) => + adapter.listThreads({ limit: input.limit }), + ); + return asResult({ ...out, exitCode: 0 as const }); + } catch (error) { + return mapError(error); + } +} + +export async function readThreadOperation( + input: z.infer, +): Promise { + try { + const out = await withAdapter(input.port, (adapter) => + adapter.readThread({ threadId: input.threadId, limit: input.limit }), + ); + return asResult({ ...out, exitCode: 0 as const }); + } catch (error) { + return mapError(error); + } +} + +export async function sendOperation(input: z.infer): Promise { + try { + const out = await withAdapter(input.port, (adapter) => + adapter.sendMessage({ threadId: input.threadId, text: input.text }), + ); + return asResult({ + ...out, + exitCode: out.delivery === 'accepted' ? (0 as const) : (1 as const), + }); + } catch (error) { + return mapError(error); + } +} + +export async function waitReplyOperation( + input: z.infer, +): Promise { + try { + const out = await withAdapter(input.port, (adapter) => + adapter.waitForReply({ threadId: input.threadId, timeoutMs: input.timeoutMs }), + ); + return asResult({ + ...out, + exitCode: out.delivery === 'replied' ? (0 as const) : (1 as const), + }); + } catch (error) { + return mapError(error); + } +} + +export function resultText(result: OperationResult): string { + if (result.error) return String(result.error); + if (result.reachable === true) { + const backend = result.appServerFallback && typeof result.appServerFallback === 'object' + ? ` cdp + app-server probe` + : ''; + return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; + } + if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); + if (Array.isArray(result.threads)) { + return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; + } + if (Array.isArray(result.turns)) { + return `${result.turns.length} turns on ${result.threadId} via ${result.backend ?? 'unknown'}`; + } + if (result.delivery === 'accepted') { + return `Sent on ${result.threadId} via ${result.backend}${result.experimental ? ' (experimental)' : ''}`; + } + if (result.delivery === 'replied') { + return String(result.reply ?? 'replied'); + } + if (result.delivery) return `delivery ${result.delivery}`; + return JSON.stringify(result); +} diff --git a/src/core/chatgpt-desktop/types.ts b/src/core/chatgpt-desktop/types.ts new file mode 100644 index 0000000..a6f7a43 --- /dev/null +++ b/src/core/chatgpt-desktop/types.ts @@ -0,0 +1,75 @@ +export type ChatGptDesktopBackend = 'cdp' | 'app-server'; + +export type ChatGptDesktopTarget = { + readonly targetId: string; + readonly type: string; + readonly title: string; + readonly url: string; + readonly attached: boolean; +}; + +export type ChatGptDesktopThread = { + readonly threadId: string; + readonly title: string; + readonly pinned: boolean; + readonly selected: boolean; + readonly kind: string; +}; + +export type ChatGptDesktopTurn = { + readonly turnKey: string; + readonly role: 'user' | 'assistant' | 'status'; + readonly text: string; +}; + +export type ChatGptDesktopStatus = { + readonly reachable: boolean; + readonly port: number; + readonly host: '127.0.0.1'; + readonly browser?: string; + readonly protocolVersion?: string; + readonly webSocketDebuggerUrl?: string; + readonly targetCount?: number; + readonly mainWindowTargetId?: string | null; + readonly appServerFallback?: { + readonly reachable: boolean; + readonly mode?: string; + readonly socketPath?: string; + }; + readonly message: string; + readonly exitCode: 0 | 1; +}; + +export type ListThreadsResult = { + readonly threads: readonly ChatGptDesktopThread[]; + readonly backend: ChatGptDesktopBackend; + readonly limit: number; +}; + +export type ReadThreadResult = { + readonly threadId: string; + readonly turns: readonly ChatGptDesktopTurn[]; + readonly backend: ChatGptDesktopBackend; + readonly limit: number; +}; + +export type SendMessageResult = { + readonly threadId: string; + readonly backend: ChatGptDesktopBackend; + readonly experimental: boolean; + readonly delivery: 'accepted' | 'rejected' | 'unknown'; + readonly message?: string; +}; + +export type WaitForReplyResult = { + readonly threadId: string; + readonly reply: string; + readonly backend: ChatGptDesktopBackend; + readonly experimental: boolean; + readonly delivery: 'replied' | 'timeout' | 'rejected' | 'unknown'; +}; + +export type OpenThreadResult = { + readonly threadId: string; + readonly backend: ChatGptDesktopBackend; +}; diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx new file mode 100644 index 0000000..ee995ca --- /dev/null +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx @@ -0,0 +1,38 @@ +import { Agent } from '@agent-bundle/runtime'; +import { defineTool } from 'agent-bundle/routes'; +import { + listThreadsOperation, + listThreadsSchema as inputSchema, + resultSchema, + resultText, +} from '../../../core/chatgpt-desktop/routes.js'; + +export { inputSchema }; + +export default defineTool( + { + title: 'ChatGPT Desktop list threads', + description: + 'List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend "cdp" or "app-server".', + annotations: { readOnlyHint: true }, + inputSchema, + resultSchema, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { type: 'number' }, + limit: { type: 'number', description: 'Maximum threads (1-200).' }, + }, + required: [], + }, + }, + async (input) => { + const out = await listThreadsOperation(input); + return ( + + {resultText(out)} + + ); + }, +); diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx new file mode 100644 index 0000000..0a6b8b2 --- /dev/null +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx @@ -0,0 +1,39 @@ +import { Agent } from '@agent-bundle/runtime'; +import { defineTool } from 'agent-bundle/routes'; +import { + readThreadOperation, + readThreadSchema as inputSchema, + resultSchema, + resultText, +} from '../../../core/chatgpt-desktop/routes.js'; + +export { inputSchema }; + +export default defineTool( + { + title: 'ChatGPT Desktop read thread', + description: + 'Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.', + annotations: { readOnlyHint: true }, + inputSchema, + resultSchema, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { type: 'number' }, + threadId: { type: 'string' }, + limit: { type: 'number' }, + }, + required: ['threadId'], + }, + }, + async (input) => { + const out = await readThreadOperation(input); + return ( + + {resultText(out)} + + ); + }, +); diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx new file mode 100644 index 0000000..fb788e6 --- /dev/null +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx @@ -0,0 +1,40 @@ +import { Agent } from '@agent-bundle/runtime'; +import { defineTool } from 'agent-bundle/routes'; +import { + resultSchema, + resultText, + sendOperation, + sendSchema as inputSchema, +} from '../../../core/chatgpt-desktop/routes.js'; + +export { inputSchema }; + +export default defineTool( + { + title: 'ChatGPT Desktop send', + description: + 'EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.', + annotations: { readOnlyHint: false }, + inputSchema, + resultSchema, + render: { maxElapsedMs: 120000 }, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { type: 'number' }, + threadId: { type: 'string', description: 'Sidebar thread id; omit to start/use a new chat.' }, + text: { type: 'string' }, + }, + required: ['text'], + }, + }, + async (input) => { + const out = await sendOperation(input); + return ( + + {resultText(out)} + + ); + }, +); diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx new file mode 100644 index 0000000..e3308d0 --- /dev/null +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx @@ -0,0 +1,40 @@ +import { Agent } from '@agent-bundle/runtime'; +import { defineTool } from 'agent-bundle/routes'; +import { + resultSchema, + resultText, + statusOperation, + statusSchema as inputSchema, +} from '../../../core/chatgpt-desktop/routes.js'; + +export { inputSchema }; + +export default defineTool( + { + title: 'ChatGPT Desktop status', + description: + 'Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.', + annotations: { readOnlyHint: true }, + inputSchema, + resultSchema, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number', + description: 'Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).', + }, + }, + required: [], + }, + }, + async (input) => { + const out = await statusOperation(input); + return ( + + {resultText(out)} + + ); + }, +); diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx new file mode 100644 index 0000000..8ee0146 --- /dev/null +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx @@ -0,0 +1,40 @@ +import { Agent } from '@agent-bundle/runtime'; +import { defineTool } from 'agent-bundle/routes'; +import { + resultSchema, + resultText, + waitReplyOperation, + waitReplySchema as inputSchema, +} from '../../../core/chatgpt-desktop/routes.js'; + +export { inputSchema }; + +export default defineTool( + { + title: 'ChatGPT Desktop wait for reply', + description: + 'EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.', + annotations: { readOnlyHint: true }, + inputSchema, + resultSchema, + render: { maxElapsedMs: 660000 }, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { type: 'number' }, + threadId: { type: 'string' }, + timeoutMs: { type: 'number' }, + }, + required: ['threadId'], + }, + }, + async (input) => { + const out = await waitReplyOperation(input); + return ( + + {resultText(out)} + + ); + }, +); diff --git a/test/host-tool-inventory.test.js b/test/host-tool-inventory.test.js index 6e76dab..075c462 100644 --- a/test/host-tool-inventory.test.js +++ b/test/host-tool-inventory.test.js @@ -11,7 +11,17 @@ const config = JSON.parse(await readFile(new URL('../artifact/.mcp.json', import const entry = config.mcpServers['grok-bot'].args[0].replace('${CLAUDE_PLUGIN_ROOT}', resolve('artifact')); const codex = ['codex_send', 'codex_threads', 'codex_wait', 'codex_watch', 'gbot_codex_respond']; const grok = ['gbot_send', 'gbot_thread', 'gbot_grok_approvals', 'gbot_grok_respond']; -const shared = ['claude_send', 'gbot_bridge_start', 'gbot_bridge_status', 'gbot_bridge_stop']; +const shared = [ + 'chatgpt_desktop_list_threads', + 'chatgpt_desktop_read_thread', + 'chatgpt_desktop_send', + 'chatgpt_desktop_status', + 'chatgpt_desktop_wait_reply', + 'claude_send', + 'gbot_bridge_start', + 'gbot_bridge_status', + 'gbot_bridge_stop', +]; test('built MCP artifact exposes the other host tools and shared bridge controls', async () => { for (const [name, hidden] of [['codex_cli_rs', codex], ['Grok Bot', grok], ['Cursor', []]]) { diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts new file mode 100644 index 0000000..c247e93 --- /dev/null +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -0,0 +1,316 @@ +import { createServer, type Server } from 'node:http'; +import type { AddressInfo } from 'node:net'; + +import { afterEach, describe, expect, it } from '@rstest/core'; +import { invokeCli, invokeMcpTool, listMcpSurface } from 'agent-bundle/test'; + +import type { ChatGptDesktopAdapter } from '../../src/core/chatgpt-desktop/adapter.js'; +import { + CdpHostRejectedError, + NotImplementedError, + assertLoopbackHostname, + chatgptDesktopRelaunchCommand, + forceLoopbackWebSocketUrl, + setChatGptDesktopAdapterForTests, +} from '../../src/core/chatgpt-desktop/index.js'; + +const desktopTools = [ + 'chatgpt_desktop_list_threads', + 'chatgpt_desktop_read_thread', + 'chatgpt_desktop_send', + 'chatgpt_desktop_status', + 'chatgpt_desktop_wait_reply', +] as const; + +function fakeAdapter(overrides: Partial = {}): ChatGptDesktopAdapter { + const base: ChatGptDesktopAdapter = { + async connect() {}, + async listTargets() { + return [ + { + targetId: 'main', + type: 'page', + title: 'ChatGPT', + url: 'app://-/index.html', + attached: true, + }, + ]; + }, + async listThreads({ limit = 50 } = {}) { + return { + backend: 'cdp', + limit, + threads: [ + { + threadId: 'local:11111111-1111-1111-1111-111111111111', + title: 'Scaffold thread', + pinned: false, + selected: true, + kind: 'local', + }, + ].slice(0, limit), + }; + }, + async readThread({ threadId, limit = 100 }) { + return { + threadId, + backend: 'cdp', + limit, + turns: [ + { turnKey: 'u1', role: 'user', text: 'hello' }, + { turnKey: 'a1', role: 'assistant', text: 'hi there' }, + ], + }; + }, + async sendMessage({ threadId, text }) { + return { + threadId: threadId ?? 'new', + backend: 'cdp', + experimental: true, + delivery: 'accepted', + message: text, + }; + }, + async waitForReply({ threadId }) { + return { + threadId, + reply: 'hi there', + backend: 'cdp', + experimental: true, + delivery: 'replied', + }; + }, + async openThread(threadId) { + return { threadId, backend: 'cdp' }; + }, + async status() { + return { + reachable: true, + port: 9222, + host: '127.0.0.1', + browser: 'fake', + message: 'ok', + exitCode: 0, + }; + }, + async close() {}, + }; + return { ...base, ...overrides }; +} + +afterEach(() => { + setChatGptDesktopAdapterForTests(null); +}); + +describe('chatgpt-desktop loopback + relaunch helpers', () => { + it('rejects non-loopback CDP hosts and rewrites debugger URLs to 127.0.0.1', () => { + expect(() => assertLoopbackHostname('example.com')).toThrow(CdpHostRejectedError); + expect(() => forceLoopbackWebSocketUrl('ws://10.0.0.2:9222/devtools/browser/x')).toThrow( + CdpHostRejectedError, + ); + expect(forceLoopbackWebSocketUrl('ws://localhost:9222/devtools/browser/x')).toBe( + 'ws://127.0.0.1:9222/devtools/browser/x', + ); + expect(chatgptDesktopRelaunchCommand({ port: 9333 })).toContain( + '--remote-debugging-port=9333', + ); + }); +}); + +describe('chatgpt-desktop MCP tools', () => { + it('registers the five chatgpt_desktop_* tools on the grok-bot server', async () => { + const surface = await listMcpSurface({ server: 'grok-bot' }); + for (const name of desktopTools) { + expect(surface.tools.includes(name)).toBe(true); + } + }); + + it('status / list / read / send / wait_reply use the injected adapter', async () => { + setChatGptDesktopAdapterForTests(fakeAdapter()); + + const status = await invokeMcpTool('chatgpt_desktop_status', { + server: 'grok-bot', + input: {}, + }); + expect(status.isError).toBe(false); + expect(status.structuredContent).toMatchObject({ + reachable: true, + host: '127.0.0.1', + exitCode: 0, + }); + + const listed = await invokeMcpTool('chatgpt_desktop_list_threads', { + server: 'grok-bot', + input: { limit: 10 }, + }); + expect(listed.isError).toBe(false); + expect(listed.structuredContent).toMatchObject({ + backend: 'cdp', + exitCode: 0, + threads: [{ threadId: 'local:11111111-1111-1111-1111-111111111111' }], + }); + + const read = await invokeMcpTool('chatgpt_desktop_read_thread', { + server: 'grok-bot', + input: { threadId: 'local:11111111-1111-1111-1111-111111111111' }, + }); + expect(read.isError).toBe(false); + expect(read.structuredContent).toMatchObject({ + backend: 'cdp', + turns: [{ role: 'user' }, { role: 'assistant' }], + }); + + const sent = await invokeMcpTool('chatgpt_desktop_send', { + server: 'grok-bot', + input: { text: 'ping' }, + }); + expect(sent.isError).toBe(false); + expect(sent.structuredContent).toMatchObject({ + delivery: 'accepted', + backend: 'cdp', + experimental: true, + exitCode: 0, + }); + + const waited = await invokeMcpTool('chatgpt_desktop_wait_reply', { + server: 'grok-bot', + input: { threadId: 'local:11111111-1111-1111-1111-111111111111', timeoutMs: 1000 }, + }); + expect(waited.isError).toBe(false); + expect(waited.structuredContent).toMatchObject({ + delivery: 'replied', + reply: 'hi there', + exitCode: 0, + }); + }); + + it('maps NotImplementedError to a rejected not-implemented document', async () => { + setChatGptDesktopAdapterForTests( + fakeAdapter({ + async listThreads() { + throw new NotImplementedError('listThreads', 'DOM selectors pending'); + }, + }), + ); + const result = await invokeMcpTool('chatgpt_desktop_list_threads', { + server: 'grok-bot', + input: {}, + }); + expect(result.structuredContent).toMatchObject({ + delivery: 'rejected', + reason: 'not-implemented', + code: 'NOT_IMPLEMENTED', + exitCode: 1, + }); + const errorText = + result.structuredContent && + typeof result.structuredContent === 'object' && + 'error' in result.structuredContent + ? String((result.structuredContent as { error?: unknown }).error ?? '') + : ''; + expect(errorText).toMatch(/listThreads/); + }); +}); + +describe('chatgpt-desktop CLI', () => { + it('dispatches status|threads|read|send through the fake adapter', async () => { + setChatGptDesktopAdapterForTests(fakeAdapter()); + + const status = await invokeCli(['chatgpt-desktop', 'status', '--json']); + expect(status.exitCode).toBe(0); + expect(status.value).toMatchObject({ reachable: true, host: '127.0.0.1' }); + + const threads = await invokeCli(['chatgpt-desktop', 'threads', '--limit', '5', '--json']); + expect(threads.exitCode).toBe(0); + expect(threads.value).toMatchObject({ backend: 'cdp' }); + + const read = await invokeCli([ + 'chatgpt-desktop', + 'read', + 'local:11111111-1111-1111-1111-111111111111', + '--json', + ]); + expect(read.exitCode).toBe(0); + expect(read.value).toMatchObject({ backend: 'cdp' }); + + const sent = await invokeCli([ + 'chatgpt-desktop', + 'send', + '--thread-id', + 'local:11111111-1111-1111-1111-111111111111', + 'hello from cli', + '--json', + ]); + expect(sent.exitCode).toBe(0); + expect(sent.value).toMatchObject({ delivery: 'accepted', backend: 'cdp' }); + }); + + it('maps CLI NotImplemented failures onto exitCode 1', async () => { + setChatGptDesktopAdapterForTests( + fakeAdapter({ + async readThread() { + throw new NotImplementedError('readThread'); + }, + }), + ); + const read = await invokeCli([ + 'chatgpt-desktop', + 'read', + 'local:missing', + '--json', + ]); + expect(read.exitCode).toBe(1); + expect(read.value).toMatchObject({ + reason: 'not-implemented', + code: 'NOT_IMPLEMENTED', + }); + }); +}); + +describe('chatgpt-desktop CDP HTTP status probe', () => { + it('reports reachable when /json/version answers on loopback', async () => { + const server: Server = createServer((req, res) => { + if (req.url === '/json/version') { + res.writeHead(200, { 'content-type': 'application/json' }); + res.end( + JSON.stringify({ + Browser: 'Test/1', + 'Protocol-Version': '1.3', + webSocketDebuggerUrl: 'ws://127.0.0.1:9/devtools/browser/test', + }), + ); + return; + } + if (req.url === '/json/list') { + res.writeHead(200, { 'content-type': 'application/json' }); + res.end(JSON.stringify([{ id: '1', type: 'page', url: 'app://-/index.html' }])); + return; + } + res.writeHead(404); + res.end(); + }); + await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); + const { port } = server.address() as AddressInfo; + try { + const { CdpChatGptDesktopAdapter } = await import( + '../../src/core/chatgpt-desktop/cdp-adapter.js' + ); + const adapter = new CdpChatGptDesktopAdapter(); + // connect sets the port then fails on WebSocket; status still uses /json/version. + await expect(adapter.connect({ port })).rejects.toThrow(/CDP|WebSocket|ECONNREFUSED|failed/i); + const status = await adapter.status(); + expect(status).toMatchObject({ + reachable: true, + port, + host: '127.0.0.1', + browser: 'Test/1', + targetCount: 1, + exitCode: 0, + }); + } finally { + await new Promise((resolve, reject) => + server.close((error) => (error ? reject(error) : resolve())), + ); + } + }); +}); diff --git a/tests/route-unit/tools.test.ts b/tests/route-unit/tools.test.ts index 4c27af9..f21d77e 100644 --- a/tests/route-unit/tools.test.ts +++ b/tests/route-unit/tools.test.ts @@ -133,7 +133,7 @@ beforeEach(() => { describe('grok-bot MCP server', () => { it('registers messaging, conversation and managed bridge tools', async () => { const surface = await listMcpSurface({ server: 'grok-bot' }); - expect([...surface.tools].sort()).toEqual(['claude_send', 'codex_send', 'codex_threads', 'codex_wait', 'codex_watch', 'gbot_bridge_start', 'gbot_bridge_status', 'gbot_bridge_stop', 'gbot_codex_respond', 'gbot_grok_approvals', 'gbot_grok_respond', 'gbot_send', 'gbot_thread']); + expect([...surface.tools].sort()).toEqual(['chatgpt_desktop_list_threads', 'chatgpt_desktop_read_thread', 'chatgpt_desktop_send', 'chatgpt_desktop_status', 'chatgpt_desktop_wait_reply', 'claude_send', 'codex_send', 'codex_threads', 'codex_wait', 'codex_watch', 'gbot_bridge_start', 'gbot_bridge_status', 'gbot_bridge_stop', 'gbot_codex_respond', 'gbot_grok_approvals', 'gbot_grok_respond', 'gbot_send', 'gbot_thread']); }); it('lists and responds to an exact current Grok approval through the native API', async () => { From 8361ae1b4352c4c5456ee50aefb813e5730071db Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 00:43:59 +0000 Subject: [PATCH 02/26] chore: rebuild artifact with chatgpt_desktop MCP tools Include the compiled grok-bot MCP server and gbot CLI routes for the ChatGPT Desktop CDP scaffold so packed installs expose the new tools. Co-authored-by: Zack Jackson --- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 1815 ++++++++++++++--- artifact/bin/gbot.mjs | 1752 ++++++++++++++-- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 1794 ++++++++++++++-- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 1641 ++++++++++++++- 6 files changed, 6402 insertions(+), 604 deletions(-) diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 29d9f32..71bf3f8 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"7335b76e87d348f5e5f78728c8a06ecd2cfbca201255fe20fe36a7c0425d1c43"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"b85a062000aafe786ae44b4b4c7a9fd19f31690f5c37950daf944139f98a3a7e"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"85a7e88503015deb0a0b0ba5f6c26d09aa4a5b6e2a7f74af09f968d79194318c"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"7e8dfa84c0aa2495bbfeca62ca5505e6fa3bbdb511550f6c313aca18fd0c217c"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"3c68557fc05451064d6ba83e57b2052ab49f0a602a351c0dc03012bb13d8965d"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"7289ed92a861c94d6d5810b57ef6c1d9e874a01583d8c0bbdad4588fb7729c96"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"049698a5689411f659de5081d9277ccd0eb16136869bd3227856289e42e4faaf"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"218892ec3254f387f72606ce06e3d7540af2c5dc14f5d1297cbff9c185ce6de6"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 657cd48..90070de 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"d61a96cae1769391557babc3dcc881fad7b055c7f302d0f6c45c91452e2f1d6b","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"da57cb3da9b4abb18a58646cf979a3e76721b174570f05036d783dccf545cf67","sourceInputs":[{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"da166aa3832bc19b65825320b4ff6e9c8f29381d2a8a806444376f5260c615b3"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"7dfb0e5cd0117ac38650f83ce257e35f77fe71398b5e5e48c695abbf4d2d7e6c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"56454a78aaea180d78e8cd62385ef66261f1748b593aa5165e587d5975205af4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"eaa9e8c9612a3c5e03c1101e98382b0f6f7501b443153c8803d434ee545a662b"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"bd5238da2d09420c5da9a605559759f977aaf8c54df9a935637f5602580e0eb7"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/claude_send.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/claude_send.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/claude_send.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/claude_send.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/claude_send.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/claude_send.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/claude_send.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":21751,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"acf62aec7b9def107029cdaea91466a62f4a631f5c83b4ecc4b1bf7373b628f3"},{"bytes":1355295,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"7335b76e87d348f5e5f78728c8a06ecd2cfbca201255fe20fe36a7c0425d1c43"},{"bytes":2206749,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"b85a062000aafe786ae44b4b4c7a9fd19f31690f5c37950daf944139f98a3a7e"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1260964,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"85a7e88503015deb0a0b0ba5f6c26d09aa4a5b6e2a7f74af09f968d79194318c"},{"bytes":3085675,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"7e8dfa84c0aa2495bbfeca62ca5505e6fa3bbdb511550f6c313aca18fd0c217c"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281157,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"2e33b068321fe570499eb19cee5d7c499938f518830523265a053d39d876e758","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"a36888d23691b58e54be76e21b0fecf246832e06dc1328140fb31fa5253e366c","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"9ae489072a2c39c2629f0e3f43d8f6a966b8ad6e25f9be144b5522e835747454","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"f4135bee52844417625ab940db9c733d028452dd10b7fd7d3816e7d33563c445"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"c1e70d400071a7b3e444772cfcf42960d0dfb7b8401588cb8be4d7a489dc012d"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"8b3538068d035d1147916a0f43c8cb24a58e98733c624c18e102eee60184d7ac"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"cd1284db2027910b91c8f0ae7ce1d7c476c7917708018f75f5b7d73088c020de"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"7a2e819d5fc9b29660cf05d5c687165d73af5a0e553460b77e46d53ecad55372"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"fd3c13ab04777bec512e8012d4a3397605719b60887c3d60b24c54c8a2480b57"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"5280b364c75e06e5f00c254f23c21b04144e949590da0c4b02e1c2cbe582aec8"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"994bafdb1ebcd71e4bb997d66d37ad3e4fe202d72258a1408f67b63c152c888f"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"0a39297107040b2a488f6401b7b06d95bc93260318772f1fbc9d2faba2c8510b"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"af1e60e24df9d3256cc5a3cfea6afe9634c6264a8cbb807f1d4b2aaa411115db"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"04900c8c233fe6a34c24bc94fc5c0ed18913a783c2b979ca1fbf4a34afd7903d"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"56a8ea6c9618831131cdf16bb60e1b0e764a4f8c72c9557d926db94f5b7090b8"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"71a6e1498f9b663831526dca85a7390fdfb548f118aa48a8c84c8f9af2815757"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"42283e5dc746ef18b301f317e2556fa17a1af25f4aaa2bf7e77decb2425e436f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"523f8899b9f010ec6dd240e961007fedf1440674dc1995c6551aff2f0b077f54"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"f6586c0913fa64da29f9c1bd4b2ada95aefdd014eea80e802822c332d1e3aba6"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"37a181c673a583a5c0344a10367ee7222cd5aa480f10351b3b337c8c9ef62cb6"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"7dfb0e5cd0117ac38650f83ce257e35f77fe71398b5e5e48c695abbf4d2d7e6c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"7695a3ef40496df91e8d60ba248983c89b1ebdbb3f07e2ec8ffdc2271d33a85d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"976ad8b1c1fc8dae4abe07e2dcbbbb56233f467fd06b1a25d2f4ca056b38ce69"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"327e7c61d5849c82b3bb864286f207ced8979ea546b365b708c7070715501151"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"bb0f72145123dde9bf4438b9f863ddaf4781656972b17f15368c0949145f9c91"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"1ae06583bac9ae9add3371b4b5c77697c6c7492dcd1c0be1a72501876879ae76"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"56454a78aaea180d78e8cd62385ef66261f1748b593aa5165e587d5975205af4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"ee26dc07b4baade26d8154ed7b4cb69c24285f2997f016bbfb8607e728e7e6bb"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"1b4b1c04bf20e035e001db69973f313d154fcc6c9b99fc3abbe4e3a604f5c2d5"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7bfaf1abfe75bc5c2167d9053c76d33ed830a083780d2dc3017492ec3c44799d"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":21751,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"4873f4dc4b1512659a451b4b6400da0008e4760767eb8a333c3fff48966552b5"},{"bytes":1416659,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"3c68557fc05451064d6ba83e57b2052ab49f0a602a351c0dc03012bb13d8965d"},{"bytes":2273620,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"7289ed92a861c94d6d5810b57ef6c1d9e874a01583d8c0bbdad4588fb7729c96"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1331527,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"049698a5689411f659de5081d9277ccd0eb16136869bd3227856289e42e4faaf"},{"bytes":3157291,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"218892ec3254f387f72606ce06e3d7540af2c5dc14f5d1297cbff9c185ce6de6"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281157,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.","exitCode":"result","options":[{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":100,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":100,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start/use a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"a17943a11b9925112cf456b4c5466766a4bd80ec3daeea646798c750ed354516","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend \"cdp\" or \"app-server\".","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"limit":{"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start/use a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index b2ed46f..4836946 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -8609,6 +8609,219 @@ var __webpack_modules__ = { resultSchema: resultSchema }); }, + "./src/cli/chatgpt-desktop/read.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const config = { + description: 'Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).', + exitCode: 'result', + positionals: [ + 'threadId' + ], + inputJsonSchema: { + additionalProperties: false, + properties: { + limit: { + default: 100, + type: 'number' + }, + port: { + type: 'number' + }, + threadId: { + type: 'string' + } + }, + required: [ + 'threadId' + ], + type: 'object' + } + }; + const inputSchema = zod__rspack_import_2.Ikc({ + limit: zod__rspack_import_2.aig().int().min(1).max(500).default(100), + port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), + threadId: zod__rspack_import_2.YjP().min(1).max(256) + }).strict(); + async function chatgptDesktopRead({ input }) { + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.UK)(input); + const turns = Array.isArray(out.turns) ? out.turns : []; + const text = turns.length > 0 ? turns.map((turn)=>{ + const row = turn; + return `[${row.role ?? '?'} ${row.turnKey ?? ''}] ${row.text ?? ''}`; + }).join('\n\n') + `\n\nbackend: ${String(out.backend ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: text + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>chatgptDesktopRead, + resultSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_1.FD + }, { + config: config, + inputSchema: inputSchema + }); + }, + "./src/cli/chatgpt-desktop/send.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const config = { + description: 'EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.', + exitCode: 'result', + positionals: [ + 'text' + ], + inputJsonSchema: { + additionalProperties: false, + properties: { + port: { + type: 'number' + }, + text: { + type: 'array', + items: { + type: 'string' + } + }, + threadId: { + type: 'string' + } + }, + required: [ + 'text' + ], + type: 'object' + }, + render: { + maxElapsedMs: 120000 + } + }; + const inputSchema = zod__rspack_import_2.Ikc({ + port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), + text: zod__rspack_import_2.YOg(zod__rspack_import_2.YjP()).min(1), + threadId: zod__rspack_import_2.YjP().min(1).max(256).optional() + }).strict(); + async function chatgptDesktopSend({ input }) { + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.UP)({ + port: input.port, + threadId: input.threadId, + text: input.text.join(' ').trim() + }); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out) + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>chatgptDesktopSend, + resultSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_1.FD + }, { + config: config, + inputSchema: inputSchema + }); + }, + "./src/cli/chatgpt-desktop/status.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const config = { + description: 'Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.', + exitCode: 'result', + inputJsonSchema: { + additionalProperties: false, + properties: { + port: { + description: 'Local CDP port (default 9222)', + type: 'number' + } + }, + type: 'object' + } + }; + const inputSchema = zod__rspack_import_2.Ikc({ + port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() + }).strict(); + async function chatgptDesktopStatus({ input }) { + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.Uj)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out) + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>chatgptDesktopStatus, + resultSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_1.FD + }, { + config: config, + inputSchema: inputSchema + }); + }, + "./src/cli/chatgpt-desktop/threads.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const config = { + description: 'List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).', + exitCode: 'result', + inputJsonSchema: { + additionalProperties: false, + properties: { + limit: { + default: 50, + description: 'Max threads (1-200)', + type: 'number' + }, + port: { + description: 'Local CDP port', + type: 'number' + } + }, + type: 'object' + } + }; + const inputSchema = zod__rspack_import_2.Ikc({ + limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), + port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() + }).strict(); + async function chatgptDesktopThreads({ input }) { + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.tJ)(input); + const threads = Array.isArray(out.threads) ? out.threads : []; + const text = threads.length > 0 ? threads.map((thread)=>{ + const row = thread; + return `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : ''); + }).join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: text + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>chatgptDesktopThreads, + resultSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_1.FD + }, { + config: config, + inputSchema: inputSchema + }); + }, "./src/cli/claude/send.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); @@ -10736,156 +10949,1252 @@ var __webpack_modules__ = { }); } __webpack_require__.d(__webpack_exports__, { - "default": ()=>skillsRemove - }, { - config: config, - inputSchema: inputSchema, - resultSchema: resultSchema + "default": ()=>skillsRemove + }, { + config: config, + inputSchema: inputSchema, + resultSchema: resultSchema + }); + }, + "./src/cli/thread.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_4 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_3 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_format_js__rspack_import_5 = __webpack_require__("./src/core/format.js"); + var _core_history_js__rspack_import_1 = __webpack_require__("./src/core/history.js"); + var _core_transcript_js__rspack_import_6 = __webpack_require__("./src/core/transcript.js"); + var _shared_js__rspack_import_2 = __webpack_require__("./src/cli/_shared.ts"); + const config = { + description: 'Read the most recent messages in a Grok Bot bot or group thread.', + inputJsonSchema: { + additionalProperties: false, + properties: { + after: { + description: 'Return entries after this opaque entry id', + type: 'string' + }, + dir: { + description: 'Agents directory for --files mode', + type: 'string' + }, + files: { + description: 'Force the on-disk agents store', + type: 'boolean' + }, + full: { + description: 'Show full entry text in human output', + type: 'boolean' + }, + gateway: { + description: 'Force the live gateway', + type: 'boolean' + }, + historyDir: { + description: 'Directory containing history.jsonl', + type: 'string' + }, + limit: { + default: 40, + description: 'How many trailing entries to return (1-200)', + type: 'number' + }, + noHistory: { + description: 'Skip local history for this command', + type: 'boolean' + }, + root: { + description: 'Read one rooted thread by message id', + type: 'string' + }, + target: { + type: 'string' + } + }, + required: [ + 'target' + ], + type: 'object' + }, + positionals: [ + 'target' + ] + }; + const inputSchema = _shared_js__rspack_import_2.lK.extend({ + after: zod__rspack_import_3.YjP().min(1).max(1024).optional(), + full: zod__rspack_import_3.zMY().default(false), + historyDir: zod__rspack_import_3.YjP().min(1).optional(), + limit: zod__rspack_import_3.aig().int().min(1).max(200).default(40), + noHistory: zod__rspack_import_3.zMY().default(false), + root: zod__rspack_import_3.YjP().min(1).optional(), + target: zod__rspack_import_3.YjP().min(1) + }).strict().refine((input)=>input.after === undefined || input.root === undefined, '--after cannot be combined with --root'); + const resultSchema = zod__rspack_import_3.g1P(zod__rspack_import_3.YjP(), zod__rspack_import_3.Pq9()); + async function thread({ input }) { + const backend = await (0, _shared_js__rspack_import_2.FS)(input); + if (input.root !== undefined) { + const rooted = await backend.thread(input.target, input.root); + (0, _core_history_js__rspack_import_1.QX)(rooted, { + dir: input.historyDir, + disabled: input.noHistory, + event: 'thread', + rootId: input.root + }); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Result, { + value: rooted, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Text, { + children: (0, _core_format_js__rspack_import_5.oZ)(rooted, { + full: input.full + }) + }) + }); + } + const out = await backend.transcript(input.target, input.limit); + if (input.after !== undefined) { + const delta = (0, _core_transcript_js__rspack_import_6.N3)(out.transcript, { + after: input.after, + limit: input.limit + }); + const selected = { + ...out, + transcript: { + entries: delta.entries + }, + cursor: delta.cursor, + entryCount: delta.entryCount, + gapReset: delta.gapReset + }; + (0, _core_history_js__rspack_import_1.QX)(selected, { + dir: input.historyDir, + disabled: input.noHistory, + event: 'thread' + }); + const text = (0, _core_format_js__rspack_import_5.oZ)(selected, { + full: input.full + }); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Result, { + value: selected, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Text, { + children: `${text}\n\ncursor: ${delta.cursor}${delta.gapReset ? ' (gap reset)' : ''}` + }) + }); + } + (0, _core_history_js__rspack_import_1.QX)(out, { + dir: input.historyDir, + disabled: input.noHistory, + event: 'thread' + }); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Text, { + children: (0, _core_format_js__rspack_import_5.oZ)(out, { + full: input.full + }) + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>thread + }, { + config: config, + inputSchema: inputSchema, + resultSchema: resultSchema + }); + }, + "./src/core/chatgpt-desktop/app-server-fallback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); + async function appServerListThreads({ limit = 50 } = {}) { + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit + }); + return { + backend: 'app-server', + limit: out.limit, + threads: out.threads.map((thread)=>({ + threadId: String(thread.id ?? ''), + title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), + pinned: false, + selected: false, + kind: 'codex' + })) + }; + } + async function appServerReadThread({ threadId, limit = 100 }) { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + let turns = []; + try { + const read = await client.request('thread/read', { + threadId + }); + const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; + turns = normalizeTurns(raw).slice(-limit); + } catch { + const items = await client.request('thread/items/list', { + threadId, + limit: Math.min(limit, 100) + }); + turns = normalizeTurns(items.data ?? []).slice(-limit); + } + return { + threadId, + turns, + backend: 'app-server', + limit + }; + } finally{ + client.close(); + } + } + async function appServerSendMessage({ threadId, text }) { + if (!threadId) { + return { + threadId: 'new', + backend: 'app-server', + experimental: false, + delivery: 'rejected', + message: 'app-server fallback requires an existing threadId; starting a new Desktop thread needs CDP' + }; + } + const receipt = await (0, _codex_bridge_js__rspack_import_0.ZS)(threadId, text); + return { + threadId, + backend: 'app-server', + experimental: false, + delivery: receipt.delivery ?? 'accepted', + message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined + }; + } + async function appServerWaitForReply({ threadId, timeoutMs = 60000 }) { + const baseline = await appServerReadThread({ + threadId, + limit: 200 + }); + const seen = new Set(baseline.turns.map((turn)=>turn.turnKey)); + const deadline = Date.now() + timeoutMs; + while(Date.now() < deadline){ + await new Promise((resolve)=>setTimeout(resolve, 400)); + const page = await appServerReadThread({ + threadId, + limit: 200 + }); + const fresh = page.turns.filter((turn)=>!seen.has(turn.turnKey) && turn.role === 'assistant' && turn.text); + const reply = fresh.at(-1)?.text ?? ''; + if (reply) { + return { + threadId, + reply, + backend: 'app-server', + experimental: false, + delivery: 'replied' + }; + } + } + return { + threadId, + reply: '', + backend: 'app-server', + experimental: false, + delivery: 'timeout' + }; + } + async function appServerOpenThread(threadId) { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + await client.request('thread/resume', { + threadId, + excludeTurns: true + }); + return { + threadId, + backend: 'app-server' + }; + } finally{ + client.close(); + } + } + async function appServerStatusProbe() { + const status = await (0, _codex_bridge_js__rspack_import_0.MU)(); + return { + reachable: Boolean(status.reachable && status.mode === 'daemon'), + mode: typeof status.mode === 'string' ? status.mode : undefined, + socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined + }; + } + function normalizeTurns(raw) { + const turns = []; + for (const [index, item] of raw.entries()){ + if (!item || typeof item !== 'object') continue; + const row = item; + const text = typeof row.text === 'string' ? row.text : typeof row.content === 'string' ? row.content : ''; + const type = String(row.type ?? row.role ?? ''); + let role = 'assistant'; + if (/user/i.test(type)) role = 'user'; + else if (/status|system|reasoning/i.test(type) && !text) role = 'status'; + turns.push({ + turnKey: String(row.id ?? row.turnId ?? index), + role, + text + }); + } + return turns; + } + __webpack_require__.d(__webpack_exports__, { + Ab: ()=>appServerSendMessage, + Jf: ()=>appServerReadThread, + OI: ()=>appServerListThreads, + bk: ()=>appServerWaitForReply, + dM: ()=>appServerStatusProbe, + zu: ()=>appServerOpenThread + }); + }, + "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _cdp_session_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); + var _cdp_dom_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); + var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + class CdpChatGptDesktopAdapter { + #port = (0, _loopback_js__rspack_import_3.L0)(); + #session = null; + #version = null; + #pageSessionId = null; + #mainTargetId = null; + async connect({ port }) { + await this.close(); + this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + const session = new _cdp_session_js__rspack_import_1.a(this.#port); + try { + this.#version = await session.connect(); + this.#session = session; + await this.#attachMainWindow(); + } catch (error) { + session.close(); + this.#session = null; + throw error; + } + } + async listTargets() { + const session = this.#requireSession(); + const result = await session.send('Target.getTargets'); + return (0, _cdp_dom_js__rspack_import_2.Mr)(result.targetInfos ?? []); + } + async listThreads({ limit = 50 } = {}) { + const sessionId = await this.#ensurePageSession(); + const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + limit + }); + return { + threads, + backend: 'cdp', + limit + }; + } + async readThread({ threadId, limit = 100 }) { + const sessionId = await this.#ensurePageSession(); + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await delay(150); + const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + limit + }); + return { + threadId, + turns, + backend: 'cdp', + limit + }; + } + async sendMessage({ threadId, text }) { + const sessionId = await this.#ensurePageSession(); + if (threadId) { + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await delay(100); + } + await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + return { + threadId: threadId ?? 'new', + backend: 'cdp', + experimental: true, + delivery: 'accepted', + message: 'Submitted via experimental CDP composer path' + }; + } + async waitForReply({ threadId, timeoutMs = 60000 }) { + const sessionId = await this.#ensurePageSession(); + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + const deadline = Date.now() + timeoutMs; + let previousKeys = new Set(); + let lastAssistant = ''; + let stable = 0; + const baseline = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + limit: 500 + }); + previousKeys = new Set(baseline.map((t)=>t.turnKey)); + while(Date.now() < deadline){ + await delay(400); + const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + limit: 500 + }); + const fresh = turns.filter((t)=>!previousKeys.has(t.turnKey) && t.role === 'assistant'); + const candidate = fresh.at(-1)?.text ?? ''; + if (candidate && candidate === lastAssistant) { + stable += 1; + if (stable >= 3) { + return { + threadId, + reply: candidate, + backend: 'cdp', + experimental: true, + delivery: 'replied' + }; + } + } else if (candidate) { + lastAssistant = candidate; + stable = 0; + } + } + return { + threadId, + reply: lastAssistant, + backend: 'cdp', + experimental: true, + delivery: lastAssistant ? 'replied' : 'timeout' + }; + } + async openThread(threadId) { + const sessionId = await this.#ensurePageSession(); + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + return { + threadId, + backend: 'cdp' + }; + } + async status() { + try { + const version = this.#version ?? await _cdp_session_js__rspack_import_1.a.fetchVersion(this.#port); + let targetCount; + let mainWindowTargetId; + if (this.#session && !this.#session.closed) { + const targets = await this.listTargets(); + targetCount = targets.length; + mainWindowTargetId = (0, _cdp_dom_js__rspack_import_2.C2)(targets)?.targetId ?? null; + } else { + const list = await _cdp_session_js__rspack_import_1.a.fetchJsonList(this.#port); + targetCount = list.length; + } + return { + reachable: true, + port: this.#port, + host: '127.0.0.1', + browser: typeof version.Browser === 'string' ? version.Browser : undefined, + protocolVersion: typeof version['Protocol-Version'] === 'string' ? version['Protocol-Version'] : undefined, + webSocketDebuggerUrl: typeof version.webSocketDebuggerUrl === 'string' ? version.webSocketDebuggerUrl : undefined, + targetCount, + mainWindowTargetId: mainWindowTargetId ?? this.#mainTargetId, + message: 'ChatGPT Desktop CDP endpoint reachable on 127.0.0.1', + exitCode: 0 + }; + } catch (error) { + return { + reachable: false, + port: this.#port, + host: '127.0.0.1', + message: error instanceof Error ? error.message : 'ChatGPT Desktop CDP endpoint unreachable on 127.0.0.1', + exitCode: 1 + }; + } + } + async close() { + this.#pageSessionId = null; + this.#mainTargetId = null; + this.#version = null; + this.#session?.close(); + this.#session = null; + } + async #attachMainWindow() { + const targets = await this.listTargets(); + const main = (0, _cdp_dom_js__rspack_import_2.C2)(targets); + if (!main) { + throw new _errors_js__rspack_import_0.sO(`No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`); + } + const attached = await this.#requireSession().send('Target.attachToTarget', { + targetId: main.targetId, + flatten: true + }); + this.#mainTargetId = main.targetId; + this.#pageSessionId = attached.sessionId; + } + async #ensurePageSession() { + this.#requireSession(); + if (!this.#pageSessionId) await this.#attachMainWindow(); + if (!this.#pageSessionId) { + throw new _errors_js__rspack_import_0.sO('Failed to attach to ChatGPT Desktop main window'); + } + return this.#pageSessionId; + } + #requireSession() { + if (!this.#session || this.#session.closed) { + throw new _errors_js__rspack_import_0.sO('Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.'); + } + return this.#session; + } + } + function delay(ms) { + return new Promise((resolve)=>setTimeout(resolve, ms)); + } + __webpack_require__.d(__webpack_exports__, { + a: ()=>CdpChatGptDesktopAdapter + }); + }, + "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + const MAIN_WINDOW_URL = 'app://-/index.html'; + const ATTR = { + threadRow: 'data-app-action-sidebar-thread-row', + threadId: 'data-app-action-sidebar-thread-id', + threadTitle: 'data-app-action-sidebar-thread-title', + threadPinned: 'data-app-action-sidebar-thread-pinned', + threadSelected: 'data-app-action-sidebar-thread-selected', + threadKind: 'data-app-action-sidebar-thread-kind', + turnKey: 'data-turn-key', + userBubble: 'data-user-message-bubble', + timelineScroll: 'data-app-action-timeline-scroll', + virtualizedTurn: 'data-virtualized-turn-content' + }; + const SELECTORS = { + threadRow: `[role="button"][${ATTR.threadRow}]`, + turn: `[${ATTR.turnKey}]`, + userBubble: `[${ATTR.userBubble}]`, + timelineScroll: `[${ATTR.timelineScroll}]`, + mainSurface: 'main', + composerCandidates: [ + 'main [contenteditable="true"]', + 'main textarea', + '[data-app-action-composer] [contenteditable="true"]', + '[data-app-action-composer] textarea', + 'form [contenteditable="true"]', + 'form textarea' + ], + sendButtonCandidates: [ + 'button[data-app-action-send]', + 'button[aria-label="Send"]', + 'button[aria-label="Send message"]', + 'main button[type="submit"]' + ] + }; + function isMainWindowTarget(target) { + return target.type === 'page' && target.url === MAIN_WINDOW_URL; + } + function summarizeTargetInfos(targetInfos) { + return targetInfos.filter((t)=>typeof t.targetId === 'string' && typeof t.type === 'string').map((t)=>({ + targetId: String(t.targetId), + type: String(t.type), + title: typeof t.title === 'string' ? t.title : '', + url: typeof t.url === 'string' ? t.url : '', + attached: Boolean(t.attached) + })); + } + function pickMainWindowTarget(targets) { + return targets.find((t)=>isMainWindowTarget(t)) ?? null; + } + const LIST_THREADS_EXPRESSION = `(() => { + const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); + return rows.map((row) => ({ + threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || '', + title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), + pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', + selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', + kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + })).filter((t) => t.threadId); +})()`; + function openThreadExpression(threadId) { + return `(() => { + const id = ${JSON.stringify(threadId)}; + const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); + const row = rows.find((el) => el.getAttribute(${JSON.stringify(ATTR.threadId)}) === id); + if (!row) return { ok: false, error: 'thread-not-found' }; + row.click(); + return { ok: true, threadId: id }; + })()`; + } + const READ_THREAD_EXPRESSION = `(() => { + const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + const mains = Array.from(document.querySelectorAll('main')); + const surface = mains.length >= 2 ? mains[1] : (mains[0] || document.body); + const root = scroll || surface; + const collected = new Map(); + const statusRe = /^Worked for \\d+s$/i; + const harvest = () => { + for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { + const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; + if (!turnKey || collected.has(turnKey)) continue; + const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); + const text = (el.innerText || '').trim(); + let role = 'assistant'; + if (user) role = 'user'; + else if (!text || statusRe.test(text)) role = 'status'; + collected.set(turnKey, { turnKey, role, text }); + } + }; + const maxPasses = 80; + let stable = 0; + let lastSize = -1; + if (scroll) scroll.scrollTop = 0; + for (let i = 0; i < maxPasses; i++) { + harvest(); + if (collected.size === lastSize) { + stable += 1; + if (stable >= 3) break; + } else { + stable = 0; + lastSize = collected.size; + } + if (scroll) { + const next = Math.min(scroll.scrollHeight, scroll.scrollTop + Math.max(scroll.clientHeight, 200)); + if (next <= scroll.scrollTop && stable >= 1) break; + scroll.scrollTop = next; + } else { + break; + } + } + harvest(); + return Array.from(collected.values()); +})()`; + function sendMessageExpression(text) { + const composers = JSON.stringify([ + ...SELECTORS.composerCandidates + ]); + const buttons = JSON.stringify([ + ...SELECTORS.sendButtonCandidates + ]); + return `(() => { + const text = ${JSON.stringify(text)}; + const composers = ${composers}; + let composer = null; + for (const sel of composers) { + composer = document.querySelector(sel); + if (composer) break; + } + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.focus(); + if (composer.isContentEditable) { + composer.textContent = text; + composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: text, inputType: 'insertText' })); + } else if ('value' in composer) { + composer.value = text; + composer.dispatchEvent(new Event('input', { bubbles: true })); + } else { + return { ok: false, error: 'composer-unsupported' }; + } + const buttons = ${buttons}; + let sent = false; + for (const sel of buttons) { + const btn = document.querySelector(sel); + if (btn && !btn.disabled) { btn.click(); sent = true; break; } + } + if (!sent) { + composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true })); + composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', bubbles: true })); + } + return { ok: true, sentVia: sent ? 'button' : 'enter' }; + })()`; + } + async function listThreadsFromDom(session, sessionId, { limit = 50 } = {}) { + const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { + sessionId + }); + if (!Array.isArray(rows)) return []; + return rows.slice(0, limit).map((row)=>({ + threadId: String(row.threadId), + title: String(row.title ?? ''), + pinned: Boolean(row.pinned), + selected: Boolean(row.selected), + kind: String(row.kind ?? 'unknown') + })); + } + async function openThreadInDom(session, sessionId, threadId) { + const result = await session.evaluate(openThreadExpression(threadId), { + sessionId + }); + if (!result?.ok) { + throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); + } + } + async function readTurnsFromDom(session, sessionId, { limit = 100 } = {}) { + const turns = await session.evaluate(READ_THREAD_EXPRESSION, { + sessionId + }); + if (!Array.isArray(turns)) return []; + return turns.slice(-limit).map((turn)=>({ + turnKey: String(turn.turnKey), + role: turn.role === 'user' || turn.role === 'status' ? turn.role : 'assistant', + text: String(turn.text ?? '') + })); + } + async function sendMessageInDom(session, sessionId, text) { + try { + await session.send('Input.insertText', { + text + }, { + sessionId + }); + } catch {} + const result = await session.evaluate(sendMessageExpression(text), { + sessionId + }); + if (!result?.ok) { + throw new Error(result?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${result?.error ?? 'unknown'}`); + } + return { + sentVia: result.sentVia ?? 'unknown' + }; + } + __webpack_require__.d(__webpack_exports__, { + AY: ()=>listThreadsFromDom, + C2: ()=>pickMainWindowTarget, + JU: ()=>readTurnsFromDom, + Kl: ()=>openThreadInDom, + Mr: ()=>summarizeTargetInfos, + lh: ()=>sendMessageInDom + }); + }, + "./src/core/chatgpt-desktop/cdp-session.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _loopback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + class CdpSession { + #port; + #ws = null; + #nextId = 1; + #pending = new Map(); + #closed = false; + constructor(port){ + this.#port = port; + } + get port() { + return this.#port; + } + get closed() { + return this.#closed || this.#ws === null || this.#ws.readyState === WebSocket.CLOSED; + } + static async fetchVersion(port, { signal } = {}) { + const base = (0, _loopback_js__rspack_import_1.NJ)(port); + let response; + try { + response = await fetch(`${base}/json/version`, { + signal + }); + } catch (error) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/version: ` + (error instanceof Error ? error.message : String(error))); + } + if (!response.ok) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP /json/version returned HTTP ${response.status}`); + } + return await response.json(); + } + static async fetchJsonList(port, { signal } = {}) { + const base = (0, _loopback_js__rspack_import_1.NJ)(port); + let response; + try { + response = await fetch(`${base}/json/list`, { + signal + }); + } catch (error) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/list: ` + (error instanceof Error ? error.message : String(error))); + } + if (!response.ok) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP /json/list returned HTTP ${response.status}`); + } + const body = await response.json(); + return Array.isArray(body) ? body : []; + } + async connect({ signal } = {}) { + if (this.#ws && !this.closed) { + throw new Error('CDP session already connected'); + } + const version = await CdpSession.fetchVersion(this.#port, { + signal + }); + const rawUrl = version.webSocketDebuggerUrl; + if (typeof rawUrl !== 'string' || !rawUrl) { + throw new _errors_js__rspack_import_0.sO('CDP /json/version omitted webSocketDebuggerUrl'); + } + const url = (0, _loopback_js__rspack_import_1.jv)(rawUrl); + const parsed = new URL(url); + (0, _loopback_js__rspack_import_1.tb)(parsed.hostname); + await new Promise((resolve, reject)=>{ + const ws = new WebSocket(url); + this.#ws = ws; + const onAbort = ()=>{ + ws.close(); + reject(new Error('CDP connect aborted')); + }; + signal?.addEventListener('abort', onAbort, { + once: true + }); + ws.addEventListener('open', ()=>{ + signal?.removeEventListener('abort', onAbort); + resolve(); + }, { + once: true + }); + ws.addEventListener('error', ()=>{ + signal?.removeEventListener('abort', onAbort); + reject(new _errors_js__rspack_import_0.sO(`CDP WebSocket failed for ${url}`)); + }, { + once: true + }); + ws.addEventListener('message', (event)=>this.#onMessage(event.data)); + ws.addEventListener('close', ()=>{ + this.#closed = true; + for (const [, pending] of this.#pending){ + pending.reject(new Error('CDP WebSocket closed')); + } + this.#pending.clear(); + }); + }); + this.#closed = false; + return version; + } + async send(method, params, { sessionId } = {}) { + if (!this.#ws || this.#ws.readyState !== WebSocket.OPEN) { + throw new _errors_js__rspack_import_0.sO('CDP session is not connected'); + } + const id = this.#nextId++; + const payload = { + id, + method + }; + if (params !== undefined) payload.params = params; + if (sessionId !== undefined) payload.sessionId = sessionId; + return await new Promise((resolve, reject)=>{ + this.#pending.set(id, { + resolve: (value)=>resolve(value), + reject + }); + this.#ws.send(JSON.stringify(payload)); + }); + } + async evaluate(expression, { sessionId, awaitPromise = true } = {}) { + const result = await this.send('Runtime.evaluate', { + expression, + returnByValue: true, + awaitPromise + }, { + sessionId + }); + if (result.exceptionDetails) { + const text = result.exceptionDetails.exception?.description || result.exceptionDetails.text || 'Runtime.evaluate failed'; + throw new Error(text); + } + return result.result?.value; + } + close() { + this.#closed = true; + this.#ws?.close(); + this.#ws = null; + } + #onMessage(data) { + let message; + try { + message = JSON.parse(String(data)); + } catch { + return; + } + if (typeof message.id !== 'number') return; + const pending = this.#pending.get(message.id); + if (!pending) return; + this.#pending.delete(message.id); + if (message.error) { + pending.reject(new Error(message.error.message || 'CDP error')); + return; + } + pending.resolve(message.result); + } + } + __webpack_require__.d(__webpack_exports__, { + a: ()=>CdpSession + }); + }, + "./src/core/chatgpt-desktop/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + class NotImplementedError extends Error { + code = 'NOT_IMPLEMENTED'; + delivery = 'rejected'; + reason = 'not-implemented'; + constructor(operation, detail){ + super(detail ? `ChatGPT Desktop ${operation} is not implemented: ${detail}` : `ChatGPT Desktop ${operation} is not implemented`); + this.name = 'NotImplementedError'; + } + } + class CdpHostRejectedError extends Error { + code = 'CDP_HOST_REJECTED'; + delivery = 'rejected'; + reason = 'cdp-host-rejected'; + constructor(host){ + super(`ChatGPT Desktop CDP rejects non-loopback host ${JSON.stringify(host)}. ` + 'Connect to 127.0.0.1 only; there is no remote transport.'); + this.name = 'CdpHostRejectedError'; + } + } + class CdpUnreachableError extends Error { + code = 'CDP_UNREACHABLE'; + delivery = 'rejected'; + reason = 'cdp-unreachable'; + constructor(message){ + super(message); + this.name = 'CdpUnreachableError'; + } + } + __webpack_require__.d(__webpack_exports__, { + EH: ()=>NotImplementedError, + c$: ()=>CdpHostRejectedError, + sO: ()=>CdpUnreachableError + }); + }, + "./src/core/chatgpt-desktop/facade.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _cdp_adapter_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-adapter.ts"); + var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); + var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + class ChatGptDesktopFacade { + #cdp; + #port; + #cdpConnected = false; + constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)()){ + this.#cdp = cdp; + this.#port = port; + } + async connect({ port }) { + this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + try { + await this.#cdp.connect({ + port: this.#port + }); + this.#cdpConnected = true; + } catch (error) { + this.#cdpConnected = false; + throw error; + } + } + async listTargets() { + await this.#ensureCdp(); + return this.#cdp.listTargets(); + } + async listThreads(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.listThreads(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.OI)(options); + } + } + async readThread(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.readThread(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.Jf)(options); + } + } + async sendMessage(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.sendMessage(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.Ab)(options); + } + } + async waitForReply(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.waitForReply(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.bk)(options); + } + } + async openThread(threadId) { + try { + await this.#ensureCdp(); + return await this.#cdp.openThread(threadId); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.zu)(threadId); + } + } + async status() { + const cdpStatus = await this.#cdp.status(); + let appServerFallback; + try { + appServerFallback = await (0, _app_server_fallback_js__rspack_import_1.dM)(); + } catch { + appServerFallback = { + reachable: false + }; + } + const reachable = cdpStatus.reachable || Boolean(appServerFallback?.reachable); + return { + ...cdpStatus, + port: this.#port, + appServerFallback, + reachable, + message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server fallback is available' : cdpStatus.message, + exitCode: reachable ? 0 : 1 + }; + } + async close() { + this.#cdpConnected = false; + await this.#cdp.close(); + } + async #ensureCdp() { + if (this.#cdpConnected) return; + await this.#cdp.connect({ + port: this.#port + }); + this.#cdpConnected = true; + } + } + function isCdpFailure(error) { + if (error instanceof _errors_js__rspack_import_2.sO) return true; + if (error instanceof _errors_js__rspack_import_2.EH) return false; + if (error && typeof error === 'object' && 'code' in error) { + const code = String(error.code); + return code === 'CDP_UNREACHABLE' || code === 'CDP_HOST_REJECTED'; + } + return false; + } + let activeAdapter = null; + function getChatGptDesktopAdapter() { + if (!activeAdapter) activeAdapter = new ChatGptDesktopFacade(); + return activeAdapter; + } + function setChatGptDesktopAdapterForTests(adapter) { + activeAdapter = adapter; + } + __webpack_require__.d(__webpack_exports__, { + PP: ()=>getChatGptDesktopAdapter + }); + }, + "./src/core/chatgpt-desktop/loopback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + const LOOPBACK = new Set([ + '127.0.0.1', + 'localhost', + '::1' + ]); + const DEFAULT_CDP_PORT = 9222; + const CDP_LOOPBACK_HOST = '127.0.0.1'; + function isLoopbackHostname(hostname) { + const host = String(hostname || '').toLowerCase().replace(/^\[|\]$/g, ''); + return LOOPBACK.has(host); + } + function assertLoopbackHostname(hostname) { + if (!isLoopbackHostname(hostname)) { + throw new _errors_js__rspack_import_0.c$(hostname); + } + } + function cdpHttpBase(port) { + if (!Number.isInteger(port) || port < 1 || port > 65535) { + throw new RangeError('CDP port must be an integer 1-65535'); + } + return `http://${CDP_LOOPBACK_HOST}:${port}`; + } + function forceLoopbackWebSocketUrl(raw) { + let url; + try { + url = new URL(raw); + } catch { + throw new _errors_js__rspack_import_0.c$(String(raw)); + } + assertLoopbackHostname(url.hostname); + if (url.protocol !== 'ws:' && url.protocol !== 'wss:') { + throw new Error(`Expected ws(s) debugger URL, got ${url.protocol}`); + } + url.hostname = CDP_LOOPBACK_HOST; + url.protocol = 'ws:'; + return url.toString(); + } + function resolveCdpPort(env = process.env, explicit) { + if (explicit !== undefined) { + if (!Number.isInteger(explicit) || explicit < 1 || explicit > 65535) { + throw new RangeError('CDP port must be an integer 1-65535'); + } + return explicit; + } + const raw = (env.CHATGPT_DESKTOP_CDP_PORT || '').trim(); + if (!raw) return DEFAULT_CDP_PORT; + const port = Number.parseInt(raw, 10); + if (!Number.isInteger(port) || port < 1 || port > 65535) { + throw new RangeError('CHATGPT_DESKTOP_CDP_PORT must be an integer 1-65535'); + } + return port; + } + __webpack_require__.d(__webpack_exports__, { + L0: ()=>resolveCdpPort, + NJ: ()=>cdpHttpBase, + jv: ()=>forceLoopbackWebSocketUrl, + tb: ()=>assertLoopbackHostname }); }, - "./src/cli/thread.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - __webpack_require__.r(__webpack_exports__); - var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); - var _agent_bundle_runtime__rspack_import_4 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); - var zod__rspack_import_3 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); - var _core_format_js__rspack_import_5 = __webpack_require__("./src/core/format.js"); - var _core_history_js__rspack_import_1 = __webpack_require__("./src/core/history.js"); - var _core_transcript_js__rspack_import_6 = __webpack_require__("./src/core/transcript.js"); - var _shared_js__rspack_import_2 = __webpack_require__("./src/cli/_shared.ts"); - const config = { - description: 'Read the most recent messages in a Grok Bot bot or group thread.', - inputJsonSchema: { - additionalProperties: false, - properties: { - after: { - description: 'Return entries after this opaque entry id', - type: 'string' - }, - dir: { - description: 'Agents directory for --files mode', - type: 'string' - }, - files: { - description: 'Force the on-disk agents store', - type: 'boolean' - }, - full: { - description: 'Show full entry text in human output', - type: 'boolean' - }, - gateway: { - description: 'Force the live gateway', - type: 'boolean' - }, - historyDir: { - description: 'Directory containing history.jsonl', - type: 'string' - }, - limit: { - default: 40, - description: 'How many trailing entries to return (1-200)', - type: 'number' - }, - noHistory: { - description: 'Skip local history for this command', - type: 'boolean' - }, - root: { - description: 'Read one rooted thread by message id', - type: 'string' - }, - target: { - type: 'string' - } - }, - required: [ - 'target' - ], - type: 'object' - }, - positionals: [ - 'target' - ] - }; - const inputSchema = _shared_js__rspack_import_2.lK.extend({ - after: zod__rspack_import_3.YjP().min(1).max(1024).optional(), - full: zod__rspack_import_3.zMY().default(false), - historyDir: zod__rspack_import_3.YjP().min(1).optional(), - limit: zod__rspack_import_3.aig().int().min(1).max(200).default(40), - noHistory: zod__rspack_import_3.zMY().default(false), - root: zod__rspack_import_3.YjP().min(1).optional(), - target: zod__rspack_import_3.YjP().min(1) - }).strict().refine((input)=>input.after === undefined || input.root === undefined, '--after cannot be combined with --root'); - const resultSchema = zod__rspack_import_3.g1P(zod__rspack_import_3.YjP(), zod__rspack_import_3.Pq9()); - async function thread({ input }) { - const backend = await (0, _shared_js__rspack_import_2.FS)(input); - if (input.root !== undefined) { - const rooted = await backend.thread(input.target, input.root); - (0, _core_history_js__rspack_import_1.QX)(rooted, { - dir: input.historyDir, - disabled: input.noHistory, - event: 'thread', - rootId: input.root + "./src/core/chatgpt-desktop/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var zod__rspack_import_4 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _codex_contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); + var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _facade_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/facade.ts"); + var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + const threadId = zod__rspack_import_4.YjP().min(1).max(256); + const statusSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional() + }).strict(); + const listThreadsSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + }).strict(); + const readThreadSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId, + limit: zod__rspack_import_4.aig().int().min(1).max(500).default(100) + }).strict(); + const sendSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId: threadId.optional(), + text: zod__rspack_import_4.YjP().min(1).max(100000) + }).strict(); + const waitReplySchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId, + timeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(60000) + }).strict(); + const resultSchema = zod__rspack_import_4.Ikc({ + exitCode: zod__rspack_import_4.KCZ([ + zod__rspack_import_4.euz(0), + zod__rspack_import_4.euz(1) + ]) + }).catchall(zod__rspack_import_4.Pq9()); + async function withAdapter(port, run) { + const adapter = (0, _facade_js__rspack_import_2.PP)(); + const resolved = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + try { + await adapter.connect({ + port: resolved }); - return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Result, { - value: rooted, - children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Text, { - children: (0, _core_format_js__rspack_import_5.oZ)(rooted, { - full: input.full - }) - }) + } catch {} + return run(adapter); + } + function asResult(value) { + return resultSchema.parse(value); + } + function mapError(error) { + if (error instanceof _errors_js__rspack_import_1.EH) { + return asResult({ + delivery: 'rejected', + reason: 'not-implemented', + code: 'NOT_IMPLEMENTED', + error: error.message, + exitCode: 1 }); } - const out = await backend.transcript(input.target, input.limit); - if (input.after !== undefined) { - const delta = (0, _core_transcript_js__rspack_import_6.N3)(out.transcript, { - after: input.after, - limit: input.limit + const base = (0, _codex_contract_js__rspack_import_0.DG)(error); + if (error && typeof error === 'object' && 'code' in error) { + return asResult({ + ...base, + code: String(error.code) }); - const selected = { + } + return asResult(base); + } + async function statusOperation(input) { + try { + const status = await withAdapter(input.port, (adapter)=>adapter.status()); + return asResult(status); + } catch (error) { + return mapError(error); + } + } + async function listThreadsOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ + limit: input.limit + })); + return asResult({ ...out, - transcript: { - entries: delta.entries - }, - cursor: delta.cursor, - entryCount: delta.entryCount, - gapReset: delta.gapReset - }; - (0, _core_history_js__rspack_import_1.QX)(selected, { - dir: input.historyDir, - disabled: input.noHistory, - event: 'thread' + exitCode: 0 }); - const text = (0, _core_format_js__rspack_import_5.oZ)(selected, { - full: input.full + } catch (error) { + return mapError(error); + } + } + async function readThreadOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ + threadId: input.threadId, + limit: input.limit + })); + return asResult({ + ...out, + exitCode: 0 }); - return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Result, { - value: selected, - children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Text, { - children: `${text}\n\ncursor: ${delta.cursor}${delta.gapReset ? ' (gap reset)' : ''}` - }) + } catch (error) { + return mapError(error); + } + } + async function sendOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.sendMessage({ + threadId: input.threadId, + text: input.text + })); + return asResult({ + ...out, + exitCode: out.delivery === 'accepted' ? 0 : 1 }); + } catch (error) { + return mapError(error); + } + } + async function waitReplyOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.waitForReply({ + threadId: input.threadId, + timeoutMs: input.timeoutMs + })); + return asResult({ + ...out, + exitCode: out.delivery === 'replied' ? 0 : 1 + }); + } catch (error) { + return mapError(error); } - (0, _core_history_js__rspack_import_1.QX)(out, { - dir: input.historyDir, - disabled: input.noHistory, - event: 'thread' - }); - return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Result, { - value: out, - children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Text, { - children: (0, _core_format_js__rspack_import_5.oZ)(out, { - full: input.full - }) - }) - }); + } + function resultText(result) { + if (result.error) return String(result.error); + if (result.reachable === true) { + const backend = result.appServerFallback && typeof result.appServerFallback === 'object' ? ` cdp + app-server probe` : ''; + return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; + } + if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); + if (Array.isArray(result.threads)) { + return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; + } + if (Array.isArray(result.turns)) { + return `${result.turns.length} turns on ${result.threadId} via ${result.backend ?? 'unknown'}`; + } + if (result.delivery === 'accepted') { + return `Sent on ${result.threadId} via ${result.backend}${result.experimental ? ' (experimental)' : ''}`; + } + if (result.delivery === 'replied') { + return String(result.reply ?? 'replied'); + } + if (result.delivery) return `delivery ${result.delivery}`; + return JSON.stringify(result); } __webpack_require__.d(__webpack_exports__, { - "default": ()=>thread + D6: ()=>resultText, + UK: ()=>readThreadOperation, + UP: ()=>sendOperation, + Uj: ()=>statusOperation, + tJ: ()=>listThreadsOperation }, { - config: config, - inputSchema: inputSchema, - resultSchema: resultSchema + FD: resultSchema }); }, "./src/core/claude-routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -25929,9 +27238,9 @@ function __webpack_require__(moduleId) { var __webpack_exports__ = {}; var node_worker_threads__rspack_import_0 = __webpack_require__("node:worker_threads"); var react__rspack_import_1 = __webpack_require__("./node_modules/react/react.react-server.js"); -var _agent_bundle_runtime_flight_server__rspack_import_41 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); -var _agent_bundle_runtime__rspack_import_39 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); -var _agent_bundle_runtime__rspack_import_40 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); +var _agent_bundle_runtime_flight_server__rspack_import_45 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); +var _agent_bundle_runtime__rspack_import_43 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); +var _agent_bundle_runtime__rspack_import_44 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); var node_url__rspack_import_2 = __webpack_require__("node:url"); var _src_cli_approvals_list_tsx__rspack_import_3 = __webpack_require__("./src/cli/approvals/list.tsx"); var _src_cli_approvals_respond_tsx__rspack_import_4 = __webpack_require__("./src/cli/approvals/respond.tsx"); @@ -25940,35 +27249,39 @@ var _src_cli_bots_delete_tsx__rspack_import_6 = __webpack_require__("./src/cli/b var _src_cli_bots_get_tsx__rspack_import_7 = __webpack_require__("./src/cli/bots/get.tsx"); var _src_cli_bots_list_tsx__rspack_import_8 = __webpack_require__("./src/cli/bots/list.tsx"); var _src_cli_bots_update_tsx__rspack_import_9 = __webpack_require__("./src/cli/bots/update.tsx"); -var _src_cli_claude_send_tsx__rspack_import_10 = __webpack_require__("./src/cli/claude/send.tsx"); -var _src_cli_codex_bridge_respond_tsx__rspack_import_11 = __webpack_require__("./src/cli/codex/bridge/respond.tsx"); -var _src_cli_codex_bridge_run_tsx__rspack_import_12 = __webpack_require__("./src/cli/codex/bridge/run.tsx"); -var _src_cli_codex_bridge_start_tsx__rspack_import_13 = __webpack_require__("./src/cli/codex/bridge/start.tsx"); -var _src_cli_codex_bridge_status_tsx__rspack_import_14 = __webpack_require__("./src/cli/codex/bridge/status.tsx"); -var _src_cli_codex_bridge_stop_tsx__rspack_import_15 = __webpack_require__("./src/cli/codex/bridge/stop.tsx"); -var _src_cli_codex_desktop_shim_tsx__rspack_import_16 = __webpack_require__("./src/cli/codex/desktop-shim.tsx"); -var _src_cli_codex_list_threads_tsx__rspack_import_17 = __webpack_require__("./src/cli/codex/list-threads.tsx"); -var _src_cli_codex_queue_tsx__rspack_import_18 = __webpack_require__("./src/cli/codex/queue.tsx"); -var _src_cli_codex_send_tsx__rspack_import_19 = __webpack_require__("./src/cli/codex/send.tsx"); -var _src_cli_codex_status_tsx__rspack_import_20 = __webpack_require__("./src/cli/codex/status.tsx"); -var _src_cli_codex_wait_tsx__rspack_import_21 = __webpack_require__("./src/cli/codex/wait.tsx"); -var _src_cli_codex_watch_tsx__rspack_import_22 = __webpack_require__("./src/cli/codex/watch.tsx"); -var _src_cli_doctor_tsx__rspack_import_23 = __webpack_require__("./src/cli/doctor.tsx"); -var _src_cli_groups_add_tsx__rspack_import_24 = __webpack_require__("./src/cli/groups/add.tsx"); -var _src_cli_groups_create_tsx__rspack_import_25 = __webpack_require__("./src/cli/groups/create.tsx"); -var _src_cli_groups_delete_tsx__rspack_import_26 = __webpack_require__("./src/cli/groups/delete.tsx"); -var _src_cli_groups_get_tsx__rspack_import_27 = __webpack_require__("./src/cli/groups/get.tsx"); -var _src_cli_groups_list_tsx__rspack_import_28 = __webpack_require__("./src/cli/groups/list.tsx"); -var _src_cli_groups_members_tsx__rspack_import_29 = __webpack_require__("./src/cli/groups/members.tsx"); -var _src_cli_groups_remove_tsx__rspack_import_30 = __webpack_require__("./src/cli/groups/remove.tsx"); -var _src_cli_groups_set_tsx__rspack_import_31 = __webpack_require__("./src/cli/groups/set.tsx"); -var _src_cli_groups_update_tsx__rspack_import_32 = __webpack_require__("./src/cli/groups/update.tsx"); -var _src_cli_history_tsx__rspack_import_33 = __webpack_require__("./src/cli/history.tsx"); -var _src_cli_send_tsx__rspack_import_34 = __webpack_require__("./src/cli/send.tsx"); -var _src_cli_skills_add_tsx__rspack_import_35 = __webpack_require__("./src/cli/skills/add.tsx"); -var _src_cli_skills_list_tsx__rspack_import_36 = __webpack_require__("./src/cli/skills/list.tsx"); -var _src_cli_skills_remove_tsx__rspack_import_37 = __webpack_require__("./src/cli/skills/remove.tsx"); -var _src_cli_thread_tsx__rspack_import_38 = __webpack_require__("./src/cli/thread.tsx"); +var _src_cli_chatgpt_desktop_read_tsx__rspack_import_10 = __webpack_require__("./src/cli/chatgpt-desktop/read.tsx"); +var _src_cli_chatgpt_desktop_send_tsx__rspack_import_11 = __webpack_require__("./src/cli/chatgpt-desktop/send.tsx"); +var _src_cli_chatgpt_desktop_status_tsx__rspack_import_12 = __webpack_require__("./src/cli/chatgpt-desktop/status.tsx"); +var _src_cli_chatgpt_desktop_threads_tsx__rspack_import_13 = __webpack_require__("./src/cli/chatgpt-desktop/threads.tsx"); +var _src_cli_claude_send_tsx__rspack_import_14 = __webpack_require__("./src/cli/claude/send.tsx"); +var _src_cli_codex_bridge_respond_tsx__rspack_import_15 = __webpack_require__("./src/cli/codex/bridge/respond.tsx"); +var _src_cli_codex_bridge_run_tsx__rspack_import_16 = __webpack_require__("./src/cli/codex/bridge/run.tsx"); +var _src_cli_codex_bridge_start_tsx__rspack_import_17 = __webpack_require__("./src/cli/codex/bridge/start.tsx"); +var _src_cli_codex_bridge_status_tsx__rspack_import_18 = __webpack_require__("./src/cli/codex/bridge/status.tsx"); +var _src_cli_codex_bridge_stop_tsx__rspack_import_19 = __webpack_require__("./src/cli/codex/bridge/stop.tsx"); +var _src_cli_codex_desktop_shim_tsx__rspack_import_20 = __webpack_require__("./src/cli/codex/desktop-shim.tsx"); +var _src_cli_codex_list_threads_tsx__rspack_import_21 = __webpack_require__("./src/cli/codex/list-threads.tsx"); +var _src_cli_codex_queue_tsx__rspack_import_22 = __webpack_require__("./src/cli/codex/queue.tsx"); +var _src_cli_codex_send_tsx__rspack_import_23 = __webpack_require__("./src/cli/codex/send.tsx"); +var _src_cli_codex_status_tsx__rspack_import_24 = __webpack_require__("./src/cli/codex/status.tsx"); +var _src_cli_codex_wait_tsx__rspack_import_25 = __webpack_require__("./src/cli/codex/wait.tsx"); +var _src_cli_codex_watch_tsx__rspack_import_26 = __webpack_require__("./src/cli/codex/watch.tsx"); +var _src_cli_doctor_tsx__rspack_import_27 = __webpack_require__("./src/cli/doctor.tsx"); +var _src_cli_groups_add_tsx__rspack_import_28 = __webpack_require__("./src/cli/groups/add.tsx"); +var _src_cli_groups_create_tsx__rspack_import_29 = __webpack_require__("./src/cli/groups/create.tsx"); +var _src_cli_groups_delete_tsx__rspack_import_30 = __webpack_require__("./src/cli/groups/delete.tsx"); +var _src_cli_groups_get_tsx__rspack_import_31 = __webpack_require__("./src/cli/groups/get.tsx"); +var _src_cli_groups_list_tsx__rspack_import_32 = __webpack_require__("./src/cli/groups/list.tsx"); +var _src_cli_groups_members_tsx__rspack_import_33 = __webpack_require__("./src/cli/groups/members.tsx"); +var _src_cli_groups_remove_tsx__rspack_import_34 = __webpack_require__("./src/cli/groups/remove.tsx"); +var _src_cli_groups_set_tsx__rspack_import_35 = __webpack_require__("./src/cli/groups/set.tsx"); +var _src_cli_groups_update_tsx__rspack_import_36 = __webpack_require__("./src/cli/groups/update.tsx"); +var _src_cli_history_tsx__rspack_import_37 = __webpack_require__("./src/cli/history.tsx"); +var _src_cli_send_tsx__rspack_import_38 = __webpack_require__("./src/cli/send.tsx"); +var _src_cli_skills_add_tsx__rspack_import_39 = __webpack_require__("./src/cli/skills/add.tsx"); +var _src_cli_skills_list_tsx__rspack_import_40 = __webpack_require__("./src/cli/skills/list.tsx"); +var _src_cli_skills_remove_tsx__rspack_import_41 = __webpack_require__("./src/cli/skills/remove.tsx"); +var _src_cli_thread_tsx__rspack_import_42 = __webpack_require__("./src/cli/thread.tsx"); const route0 = Object.assign({}, Reflect.get(_src_cli_approvals_list_tsx__rspack_import_3, 'default'), _src_cli_approvals_list_tsx__rspack_import_3); const route1 = Object.assign({}, Reflect.get(_src_cli_approvals_respond_tsx__rspack_import_4, 'default'), _src_cli_approvals_respond_tsx__rspack_import_4); const route2 = Object.assign({}, Reflect.get(_src_cli_bots_create_tsx__rspack_import_5, 'default'), _src_cli_bots_create_tsx__rspack_import_5); @@ -25976,36 +27289,40 @@ const route3 = Object.assign({}, Reflect.get(_src_cli_bots_delete_tsx__rspack_im const route4 = Object.assign({}, Reflect.get(_src_cli_bots_get_tsx__rspack_import_7, 'default'), _src_cli_bots_get_tsx__rspack_import_7); const route5 = Object.assign({}, Reflect.get(_src_cli_bots_list_tsx__rspack_import_8, 'default'), _src_cli_bots_list_tsx__rspack_import_8); const route6 = Object.assign({}, Reflect.get(_src_cli_bots_update_tsx__rspack_import_9, 'default'), _src_cli_bots_update_tsx__rspack_import_9); -const route7 = Object.assign({}, Reflect.get(_src_cli_claude_send_tsx__rspack_import_10, 'default'), _src_cli_claude_send_tsx__rspack_import_10); -const route8 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_respond_tsx__rspack_import_11, 'default'), _src_cli_codex_bridge_respond_tsx__rspack_import_11); -const route9 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_run_tsx__rspack_import_12, 'default'), _src_cli_codex_bridge_run_tsx__rspack_import_12); -const route10 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_start_tsx__rspack_import_13, 'default'), _src_cli_codex_bridge_start_tsx__rspack_import_13); -const route11 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_status_tsx__rspack_import_14, 'default'), _src_cli_codex_bridge_status_tsx__rspack_import_14); -const route12 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_stop_tsx__rspack_import_15, 'default'), _src_cli_codex_bridge_stop_tsx__rspack_import_15); -const route13 = Object.assign({}, Reflect.get(_src_cli_codex_desktop_shim_tsx__rspack_import_16, 'default'), _src_cli_codex_desktop_shim_tsx__rspack_import_16); -const route14 = Object.assign({}, Reflect.get(_src_cli_codex_list_threads_tsx__rspack_import_17, 'default'), _src_cli_codex_list_threads_tsx__rspack_import_17); -const route15 = Object.assign({}, Reflect.get(_src_cli_codex_queue_tsx__rspack_import_18, 'default'), _src_cli_codex_queue_tsx__rspack_import_18); -const route16 = Object.assign({}, Reflect.get(_src_cli_codex_send_tsx__rspack_import_19, 'default'), _src_cli_codex_send_tsx__rspack_import_19); -const route17 = Object.assign({}, Reflect.get(_src_cli_codex_status_tsx__rspack_import_20, 'default'), _src_cli_codex_status_tsx__rspack_import_20); -const route18 = Object.assign({}, Reflect.get(_src_cli_codex_wait_tsx__rspack_import_21, 'default'), _src_cli_codex_wait_tsx__rspack_import_21); -const route19 = Object.assign({}, Reflect.get(_src_cli_codex_watch_tsx__rspack_import_22, 'default'), _src_cli_codex_watch_tsx__rspack_import_22); -const route20 = Object.assign({}, Reflect.get(_src_cli_doctor_tsx__rspack_import_23, 'default'), _src_cli_doctor_tsx__rspack_import_23); -const route21 = Object.assign({}, Reflect.get(_src_cli_groups_add_tsx__rspack_import_24, 'default'), _src_cli_groups_add_tsx__rspack_import_24); -const route22 = Object.assign({}, Reflect.get(_src_cli_groups_create_tsx__rspack_import_25, 'default'), _src_cli_groups_create_tsx__rspack_import_25); -const route23 = Object.assign({}, Reflect.get(_src_cli_groups_delete_tsx__rspack_import_26, 'default'), _src_cli_groups_delete_tsx__rspack_import_26); -const route24 = Object.assign({}, Reflect.get(_src_cli_groups_get_tsx__rspack_import_27, 'default'), _src_cli_groups_get_tsx__rspack_import_27); -const route25 = Object.assign({}, Reflect.get(_src_cli_groups_list_tsx__rspack_import_28, 'default'), _src_cli_groups_list_tsx__rspack_import_28); -const route26 = Object.assign({}, Reflect.get(_src_cli_groups_members_tsx__rspack_import_29, 'default'), _src_cli_groups_members_tsx__rspack_import_29); -const route27 = Object.assign({}, Reflect.get(_src_cli_groups_remove_tsx__rspack_import_30, 'default'), _src_cli_groups_remove_tsx__rspack_import_30); -const route28 = Object.assign({}, Reflect.get(_src_cli_groups_set_tsx__rspack_import_31, 'default'), _src_cli_groups_set_tsx__rspack_import_31); -const route29 = Object.assign({}, Reflect.get(_src_cli_groups_update_tsx__rspack_import_32, 'default'), _src_cli_groups_update_tsx__rspack_import_32); -const route30 = Object.assign({}, Reflect.get(_src_cli_history_tsx__rspack_import_33, 'default'), _src_cli_history_tsx__rspack_import_33); -const route31 = Object.assign({}, Reflect.get(_src_cli_send_tsx__rspack_import_34, 'default'), _src_cli_send_tsx__rspack_import_34); -const route32 = Object.assign({}, Reflect.get(_src_cli_skills_add_tsx__rspack_import_35, 'default'), _src_cli_skills_add_tsx__rspack_import_35); -const route33 = Object.assign({}, Reflect.get(_src_cli_skills_list_tsx__rspack_import_36, 'default'), _src_cli_skills_list_tsx__rspack_import_36); -const route34 = Object.assign({}, Reflect.get(_src_cli_skills_remove_tsx__rspack_import_37, 'default'), _src_cli_skills_remove_tsx__rspack_import_37); -const route35 = Object.assign({}, Reflect.get(_src_cli_thread_tsx__rspack_import_38, 'default'), _src_cli_thread_tsx__rspack_import_38); -const pluginRoot = (0, _agent_bundle_runtime__rspack_import_39.E7)({ +const route7 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_read_tsx__rspack_import_10, 'default'), _src_cli_chatgpt_desktop_read_tsx__rspack_import_10); +const route8 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_send_tsx__rspack_import_11, 'default'), _src_cli_chatgpt_desktop_send_tsx__rspack_import_11); +const route9 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_status_tsx__rspack_import_12, 'default'), _src_cli_chatgpt_desktop_status_tsx__rspack_import_12); +const route10 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_threads_tsx__rspack_import_13, 'default'), _src_cli_chatgpt_desktop_threads_tsx__rspack_import_13); +const route11 = Object.assign({}, Reflect.get(_src_cli_claude_send_tsx__rspack_import_14, 'default'), _src_cli_claude_send_tsx__rspack_import_14); +const route12 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_respond_tsx__rspack_import_15, 'default'), _src_cli_codex_bridge_respond_tsx__rspack_import_15); +const route13 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_run_tsx__rspack_import_16, 'default'), _src_cli_codex_bridge_run_tsx__rspack_import_16); +const route14 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_start_tsx__rspack_import_17, 'default'), _src_cli_codex_bridge_start_tsx__rspack_import_17); +const route15 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_status_tsx__rspack_import_18, 'default'), _src_cli_codex_bridge_status_tsx__rspack_import_18); +const route16 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_stop_tsx__rspack_import_19, 'default'), _src_cli_codex_bridge_stop_tsx__rspack_import_19); +const route17 = Object.assign({}, Reflect.get(_src_cli_codex_desktop_shim_tsx__rspack_import_20, 'default'), _src_cli_codex_desktop_shim_tsx__rspack_import_20); +const route18 = Object.assign({}, Reflect.get(_src_cli_codex_list_threads_tsx__rspack_import_21, 'default'), _src_cli_codex_list_threads_tsx__rspack_import_21); +const route19 = Object.assign({}, Reflect.get(_src_cli_codex_queue_tsx__rspack_import_22, 'default'), _src_cli_codex_queue_tsx__rspack_import_22); +const route20 = Object.assign({}, Reflect.get(_src_cli_codex_send_tsx__rspack_import_23, 'default'), _src_cli_codex_send_tsx__rspack_import_23); +const route21 = Object.assign({}, Reflect.get(_src_cli_codex_status_tsx__rspack_import_24, 'default'), _src_cli_codex_status_tsx__rspack_import_24); +const route22 = Object.assign({}, Reflect.get(_src_cli_codex_wait_tsx__rspack_import_25, 'default'), _src_cli_codex_wait_tsx__rspack_import_25); +const route23 = Object.assign({}, Reflect.get(_src_cli_codex_watch_tsx__rspack_import_26, 'default'), _src_cli_codex_watch_tsx__rspack_import_26); +const route24 = Object.assign({}, Reflect.get(_src_cli_doctor_tsx__rspack_import_27, 'default'), _src_cli_doctor_tsx__rspack_import_27); +const route25 = Object.assign({}, Reflect.get(_src_cli_groups_add_tsx__rspack_import_28, 'default'), _src_cli_groups_add_tsx__rspack_import_28); +const route26 = Object.assign({}, Reflect.get(_src_cli_groups_create_tsx__rspack_import_29, 'default'), _src_cli_groups_create_tsx__rspack_import_29); +const route27 = Object.assign({}, Reflect.get(_src_cli_groups_delete_tsx__rspack_import_30, 'default'), _src_cli_groups_delete_tsx__rspack_import_30); +const route28 = Object.assign({}, Reflect.get(_src_cli_groups_get_tsx__rspack_import_31, 'default'), _src_cli_groups_get_tsx__rspack_import_31); +const route29 = Object.assign({}, Reflect.get(_src_cli_groups_list_tsx__rspack_import_32, 'default'), _src_cli_groups_list_tsx__rspack_import_32); +const route30 = Object.assign({}, Reflect.get(_src_cli_groups_members_tsx__rspack_import_33, 'default'), _src_cli_groups_members_tsx__rspack_import_33); +const route31 = Object.assign({}, Reflect.get(_src_cli_groups_remove_tsx__rspack_import_34, 'default'), _src_cli_groups_remove_tsx__rspack_import_34); +const route32 = Object.assign({}, Reflect.get(_src_cli_groups_set_tsx__rspack_import_35, 'default'), _src_cli_groups_set_tsx__rspack_import_35); +const route33 = Object.assign({}, Reflect.get(_src_cli_groups_update_tsx__rspack_import_36, 'default'), _src_cli_groups_update_tsx__rspack_import_36); +const route34 = Object.assign({}, Reflect.get(_src_cli_history_tsx__rspack_import_37, 'default'), _src_cli_history_tsx__rspack_import_37); +const route35 = Object.assign({}, Reflect.get(_src_cli_send_tsx__rspack_import_38, 'default'), _src_cli_send_tsx__rspack_import_38); +const route36 = Object.assign({}, Reflect.get(_src_cli_skills_add_tsx__rspack_import_39, 'default'), _src_cli_skills_add_tsx__rspack_import_39); +const route37 = Object.assign({}, Reflect.get(_src_cli_skills_list_tsx__rspack_import_40, 'default'), _src_cli_skills_list_tsx__rspack_import_40); +const route38 = Object.assign({}, Reflect.get(_src_cli_skills_remove_tsx__rspack_import_41, 'default'), _src_cli_skills_remove_tsx__rspack_import_41); +const route39 = Object.assign({}, Reflect.get(_src_cli_thread_tsx__rspack_import_42, 'default'), _src_cli_thread_tsx__rspack_import_42); +const pluginRoot = (0, _agent_bundle_runtime__rspack_import_43.E7)({ fallback: (0, node_url__rspack_import_2.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); @@ -26063,179 +27380,203 @@ const routes = Object.freeze({ name: "bots update", module: route6 }), + "cli:chatgpt-desktop/read": Object.freeze({ + id: "cli:chatgpt-desktop/read", + kind: "cli", + name: "chatgpt-desktop read", + module: route7 + }), + "cli:chatgpt-desktop/send": Object.freeze({ + id: "cli:chatgpt-desktop/send", + kind: "cli", + name: "chatgpt-desktop send", + module: route8 + }), + "cli:chatgpt-desktop/status": Object.freeze({ + id: "cli:chatgpt-desktop/status", + kind: "cli", + name: "chatgpt-desktop status", + module: route9 + }), + "cli:chatgpt-desktop/threads": Object.freeze({ + id: "cli:chatgpt-desktop/threads", + kind: "cli", + name: "chatgpt-desktop threads", + module: route10 + }), "cli:claude/send": Object.freeze({ id: "cli:claude/send", kind: "cli", name: "claude send", - module: route7 + module: route11 }), "cli:codex/bridge/respond": Object.freeze({ id: "cli:codex/bridge/respond", kind: "cli", name: "codex bridge respond", - module: route8 + module: route12 }), "cli:codex/bridge/run": Object.freeze({ id: "cli:codex/bridge/run", kind: "cli", name: "codex bridge run", - module: route9 + module: route13 }), "cli:codex/bridge/start": Object.freeze({ id: "cli:codex/bridge/start", kind: "cli", name: "codex bridge start", - module: route10 + module: route14 }), "cli:codex/bridge/status": Object.freeze({ id: "cli:codex/bridge/status", kind: "cli", name: "codex bridge status", - module: route11 + module: route15 }), "cli:codex/bridge/stop": Object.freeze({ id: "cli:codex/bridge/stop", kind: "cli", name: "codex bridge stop", - module: route12 + module: route16 }), "cli:codex/desktop-shim": Object.freeze({ id: "cli:codex/desktop-shim", kind: "cli", name: "codex desktop-shim", - module: route13 + module: route17 }), "cli:codex/list-threads": Object.freeze({ id: "cli:codex/list-threads", kind: "cli", name: "codex list-threads", - module: route14 + module: route18 }), "cli:codex/queue": Object.freeze({ id: "cli:codex/queue", kind: "cli", name: "codex queue", - module: route15 + module: route19 }), "cli:codex/send": Object.freeze({ id: "cli:codex/send", kind: "cli", name: "codex send", - module: route16 + module: route20 }), "cli:codex/status": Object.freeze({ id: "cli:codex/status", kind: "cli", name: "codex status", - module: route17 + module: route21 }), "cli:codex/wait": Object.freeze({ id: "cli:codex/wait", kind: "cli", name: "codex wait", - module: route18 + module: route22 }), "cli:codex/watch": Object.freeze({ id: "cli:codex/watch", kind: "cli", name: "codex watch", - module: route19 + module: route23 }), "cli:doctor": Object.freeze({ id: "cli:doctor", kind: "cli", name: "doctor", - module: route20 + module: route24 }), "cli:groups/add": Object.freeze({ id: "cli:groups/add", kind: "cli", name: "groups add", - module: route21 + module: route25 }), "cli:groups/create": Object.freeze({ id: "cli:groups/create", kind: "cli", name: "groups create", - module: route22 + module: route26 }), "cli:groups/delete": Object.freeze({ id: "cli:groups/delete", kind: "cli", name: "groups delete", - module: route23 + module: route27 }), "cli:groups/get": Object.freeze({ id: "cli:groups/get", kind: "cli", name: "groups get", - module: route24 + module: route28 }), "cli:groups/list": Object.freeze({ id: "cli:groups/list", kind: "cli", name: "groups list", - module: route25 + module: route29 }), "cli:groups/members": Object.freeze({ id: "cli:groups/members", kind: "cli", name: "groups members", - module: route26 + module: route30 }), "cli:groups/remove": Object.freeze({ id: "cli:groups/remove", kind: "cli", name: "groups remove", - module: route27 + module: route31 }), "cli:groups/set": Object.freeze({ id: "cli:groups/set", kind: "cli", name: "groups set", - module: route28 + module: route32 }), "cli:groups/update": Object.freeze({ id: "cli:groups/update", kind: "cli", name: "groups update", - module: route29 + module: route33 }), "cli:history": Object.freeze({ id: "cli:history", kind: "cli", name: "history", - module: route30 + module: route34 }), "cli:send": Object.freeze({ id: "cli:send", kind: "cli", name: "send", - module: route31 + module: route35 }), "cli:skills/add": Object.freeze({ id: "cli:skills/add", kind: "cli", name: "skills add", - module: route32 + module: route36 }), "cli:skills/list": Object.freeze({ id: "cli:skills/list", kind: "cli", name: "skills list", - module: route33 + module: route37 }), "cli:skills/remove": Object.freeze({ id: "cli:skills/remove", kind: "cli", name: "skills remove", - module: route34 + module: route38 }), "cli:thread": Object.freeze({ id: "cli:thread", kind: "cli", name: "thread", - module: route35 + module: route39 }) }); const requests = new Map(); @@ -26270,18 +27611,18 @@ const render = async (message)=>{ }; try { const cwd = process.cwd(); - await (0, _agent_bundle_runtime__rspack_import_40.iC)({ + await (0, _agent_bundle_runtime__rspack_import_44.iC)({ capabilities: { - command: (0, _agent_bundle_runtime__rspack_import_40.hU)(), - filesystem: (0, _agent_bundle_runtime__rspack_import_40.hU)(), - network: (0, _agent_bundle_runtime__rspack_import_40.hU)(), - projectRoot: (0, _agent_bundle_runtime__rspack_import_40.qC)({ + command: (0, _agent_bundle_runtime__rspack_import_44.hU)(), + filesystem: (0, _agent_bundle_runtime__rspack_import_44.hU)(), + network: (0, _agent_bundle_runtime__rspack_import_44.hU)(), + projectRoot: (0, _agent_bundle_runtime__rspack_import_44.qC)({ root: cwd }, 'derived') }, - host: (0, _agent_bundle_runtime__rspack_import_40.hU)('unsupported-surface'), + host: (0, _agent_bundle_runtime__rspack_import_44.hU)('unsupported-surface'), invocation: message.request, - lineage: (0, _agent_bundle_runtime__rspack_import_40.hU)('unsupported-surface'), + lineage: (0, _agent_bundle_runtime__rspack_import_44.hU)('unsupported-surface'), plugin: pluginRoot.identity, progress: { report: async (update)=>{ @@ -26294,8 +27635,8 @@ const render = async (message)=>{ }, process: processHit, signal: controller.signal, - terminal: message.terminal === undefined ? (0, _agent_bundle_runtime__rspack_import_40.hU)('not-provided') : (0, _agent_bundle_runtime__rspack_import_40.qC)(message.terminal, 'native'), - workspace: (0, _agent_bundle_runtime__rspack_import_40.qC)({ + terminal: message.terminal === undefined ? (0, _agent_bundle_runtime__rspack_import_44.hU)('not-provided') : (0, _agent_bundle_runtime__rspack_import_44.qC)(message.terminal, 'native'), + workspace: (0, _agent_bundle_runtime__rspack_import_44.qC)({ root: cwd }, 'derived') }, async ()=>{ @@ -26304,7 +27645,7 @@ const render = async (message)=>{ type: 'observed-render-start' }); const renderStartedAt = performance.now(); - const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_41.y)(composeLayouts(observedRoute, { + const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_45.y)(composeLayouts(observedRoute, { ...message.props, signal: controller.signal }, controller.signal), { diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index 7f39006..5433211 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -7017,6 +7017,219 @@ var __webpack_modules__ = { resultSchema: resultSchema }); }, + "./src/cli/chatgpt-desktop/read.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const config = { + description: 'Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).', + exitCode: 'result', + positionals: [ + 'threadId' + ], + inputJsonSchema: { + additionalProperties: false, + properties: { + limit: { + default: 100, + type: 'number' + }, + port: { + type: 'number' + }, + threadId: { + type: 'string' + } + }, + required: [ + 'threadId' + ], + type: 'object' + } + }; + const inputSchema = zod__rspack_import_2.Ikc({ + limit: zod__rspack_import_2.aig().int().min(1).max(500).default(100), + port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), + threadId: zod__rspack_import_2.YjP().min(1).max(256) + }).strict(); + async function chatgptDesktopRead({ input }) { + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.UK)(input); + const turns = Array.isArray(out.turns) ? out.turns : []; + const text = turns.length > 0 ? turns.map((turn)=>{ + const row = turn; + return `[${row.role ?? '?'} ${row.turnKey ?? ''}] ${row.text ?? ''}`; + }).join('\n\n') + `\n\nbackend: ${String(out.backend ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: text + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>chatgptDesktopRead, + resultSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_1.FD + }, { + config: config, + inputSchema: inputSchema + }); + }, + "./src/cli/chatgpt-desktop/send.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const config = { + description: 'EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.', + exitCode: 'result', + positionals: [ + 'text' + ], + inputJsonSchema: { + additionalProperties: false, + properties: { + port: { + type: 'number' + }, + text: { + type: 'array', + items: { + type: 'string' + } + }, + threadId: { + type: 'string' + } + }, + required: [ + 'text' + ], + type: 'object' + }, + render: { + maxElapsedMs: 120000 + } + }; + const inputSchema = zod__rspack_import_2.Ikc({ + port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), + text: zod__rspack_import_2.YOg(zod__rspack_import_2.YjP()).min(1), + threadId: zod__rspack_import_2.YjP().min(1).max(256).optional() + }).strict(); + async function chatgptDesktopSend({ input }) { + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.UP)({ + port: input.port, + threadId: input.threadId, + text: input.text.join(' ').trim() + }); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out) + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>chatgptDesktopSend, + resultSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_1.FD + }, { + config: config, + inputSchema: inputSchema + }); + }, + "./src/cli/chatgpt-desktop/status.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const config = { + description: 'Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.', + exitCode: 'result', + inputJsonSchema: { + additionalProperties: false, + properties: { + port: { + description: 'Local CDP port (default 9222)', + type: 'number' + } + }, + type: 'object' + } + }; + const inputSchema = zod__rspack_import_2.Ikc({ + port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() + }).strict(); + async function chatgptDesktopStatus({ input }) { + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.Uj)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out) + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>chatgptDesktopStatus, + resultSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_1.FD + }, { + config: config, + inputSchema: inputSchema + }); + }, + "./src/cli/chatgpt-desktop/threads.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const config = { + description: 'List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).', + exitCode: 'result', + inputJsonSchema: { + additionalProperties: false, + properties: { + limit: { + default: 50, + description: 'Max threads (1-200)', + type: 'number' + }, + port: { + description: 'Local CDP port', + type: 'number' + } + }, + type: 'object' + } + }; + const inputSchema = zod__rspack_import_2.Ikc({ + limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), + port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() + }).strict(); + async function chatgptDesktopThreads({ input }) { + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.tJ)(input); + const threads = Array.isArray(out.threads) ? out.threads : []; + const text = threads.length > 0 ? threads.map((thread)=>{ + const row = thread; + return `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : ''); + }).join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: text + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>chatgptDesktopThreads, + resultSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_1.FD + }, { + config: config, + inputSchema: inputSchema + }); + }, "./src/cli/claude/send.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); @@ -9235,65 +9448,1161 @@ var __webpack_modules__ = { event: 'thread', rootId: input.root }); - return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Result, { - value: rooted, - children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Text, { - children: (0, _core_format_js__rspack_import_5.oZ)(rooted, { - full: input.full - }) - }) + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Result, { + value: rooted, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Text, { + children: (0, _core_format_js__rspack_import_5.oZ)(rooted, { + full: input.full + }) + }) + }); + } + const out = await backend.transcript(input.target, input.limit); + if (input.after !== undefined) { + const delta = (0, _core_transcript_js__rspack_import_6.N3)(out.transcript, { + after: input.after, + limit: input.limit + }); + const selected = { + ...out, + transcript: { + entries: delta.entries + }, + cursor: delta.cursor, + entryCount: delta.entryCount, + gapReset: delta.gapReset + }; + (0, _core_history_js__rspack_import_1.QX)(selected, { + dir: input.historyDir, + disabled: input.noHistory, + event: 'thread' + }); + const text = (0, _core_format_js__rspack_import_5.oZ)(selected, { + full: input.full + }); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Result, { + value: selected, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Text, { + children: `${text}\n\ncursor: ${delta.cursor}${delta.gapReset ? ' (gap reset)' : ''}` + }) + }); + } + (0, _core_history_js__rspack_import_1.QX)(out, { + dir: input.historyDir, + disabled: input.noHistory, + event: 'thread' + }); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Text, { + children: (0, _core_format_js__rspack_import_5.oZ)(out, { + full: input.full + }) + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>thread + }, { + config: config, + inputSchema: inputSchema, + resultSchema: resultSchema + }); + }, + "./src/core/chatgpt-desktop/app-server-fallback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); + async function appServerListThreads({ limit = 50 } = {}) { + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit + }); + return { + backend: 'app-server', + limit: out.limit, + threads: out.threads.map((thread)=>({ + threadId: String(thread.id ?? ''), + title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), + pinned: false, + selected: false, + kind: 'codex' + })) + }; + } + async function appServerReadThread({ threadId, limit = 100 }) { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + let turns = []; + try { + const read = await client.request('thread/read', { + threadId + }); + const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; + turns = normalizeTurns(raw).slice(-limit); + } catch { + const items = await client.request('thread/items/list', { + threadId, + limit: Math.min(limit, 100) + }); + turns = normalizeTurns(items.data ?? []).slice(-limit); + } + return { + threadId, + turns, + backend: 'app-server', + limit + }; + } finally{ + client.close(); + } + } + async function appServerSendMessage({ threadId, text }) { + if (!threadId) { + return { + threadId: 'new', + backend: 'app-server', + experimental: false, + delivery: 'rejected', + message: 'app-server fallback requires an existing threadId; starting a new Desktop thread needs CDP' + }; + } + const receipt = await (0, _codex_bridge_js__rspack_import_0.ZS)(threadId, text); + return { + threadId, + backend: 'app-server', + experimental: false, + delivery: receipt.delivery ?? 'accepted', + message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined + }; + } + async function appServerWaitForReply({ threadId, timeoutMs = 60000 }) { + const baseline = await appServerReadThread({ + threadId, + limit: 200 + }); + const seen = new Set(baseline.turns.map((turn)=>turn.turnKey)); + const deadline = Date.now() + timeoutMs; + while(Date.now() < deadline){ + await new Promise((resolve)=>setTimeout(resolve, 400)); + const page = await appServerReadThread({ + threadId, + limit: 200 + }); + const fresh = page.turns.filter((turn)=>!seen.has(turn.turnKey) && turn.role === 'assistant' && turn.text); + const reply = fresh.at(-1)?.text ?? ''; + if (reply) { + return { + threadId, + reply, + backend: 'app-server', + experimental: false, + delivery: 'replied' + }; + } + } + return { + threadId, + reply: '', + backend: 'app-server', + experimental: false, + delivery: 'timeout' + }; + } + async function appServerOpenThread(threadId) { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + await client.request('thread/resume', { + threadId, + excludeTurns: true + }); + return { + threadId, + backend: 'app-server' + }; + } finally{ + client.close(); + } + } + async function appServerStatusProbe() { + const status = await (0, _codex_bridge_js__rspack_import_0.MU)(); + return { + reachable: Boolean(status.reachable && status.mode === 'daemon'), + mode: typeof status.mode === 'string' ? status.mode : undefined, + socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined + }; + } + function normalizeTurns(raw) { + const turns = []; + for (const [index, item] of raw.entries()){ + if (!item || typeof item !== 'object') continue; + const row = item; + const text = typeof row.text === 'string' ? row.text : typeof row.content === 'string' ? row.content : ''; + const type = String(row.type ?? row.role ?? ''); + let role = 'assistant'; + if (/user/i.test(type)) role = 'user'; + else if (/status|system|reasoning/i.test(type) && !text) role = 'status'; + turns.push({ + turnKey: String(row.id ?? row.turnId ?? index), + role, + text + }); + } + return turns; + } + __webpack_require__.d(__webpack_exports__, { + Ab: ()=>appServerSendMessage, + Jf: ()=>appServerReadThread, + OI: ()=>appServerListThreads, + bk: ()=>appServerWaitForReply, + dM: ()=>appServerStatusProbe, + zu: ()=>appServerOpenThread + }); + }, + "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _cdp_session_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); + var _cdp_dom_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); + var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + class CdpChatGptDesktopAdapter { + #port = (0, _loopback_js__rspack_import_3.L0)(); + #session = null; + #version = null; + #pageSessionId = null; + #mainTargetId = null; + async connect({ port }) { + await this.close(); + this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + const session = new _cdp_session_js__rspack_import_1.a(this.#port); + try { + this.#version = await session.connect(); + this.#session = session; + await this.#attachMainWindow(); + } catch (error) { + session.close(); + this.#session = null; + throw error; + } + } + async listTargets() { + const session = this.#requireSession(); + const result = await session.send('Target.getTargets'); + return (0, _cdp_dom_js__rspack_import_2.Mr)(result.targetInfos ?? []); + } + async listThreads({ limit = 50 } = {}) { + const sessionId = await this.#ensurePageSession(); + const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + limit + }); + return { + threads, + backend: 'cdp', + limit + }; + } + async readThread({ threadId, limit = 100 }) { + const sessionId = await this.#ensurePageSession(); + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await delay(150); + const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + limit + }); + return { + threadId, + turns, + backend: 'cdp', + limit + }; + } + async sendMessage({ threadId, text }) { + const sessionId = await this.#ensurePageSession(); + if (threadId) { + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await delay(100); + } + await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + return { + threadId: threadId ?? 'new', + backend: 'cdp', + experimental: true, + delivery: 'accepted', + message: 'Submitted via experimental CDP composer path' + }; + } + async waitForReply({ threadId, timeoutMs = 60000 }) { + const sessionId = await this.#ensurePageSession(); + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + const deadline = Date.now() + timeoutMs; + let previousKeys = new Set(); + let lastAssistant = ''; + let stable = 0; + const baseline = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + limit: 500 + }); + previousKeys = new Set(baseline.map((t)=>t.turnKey)); + while(Date.now() < deadline){ + await delay(400); + const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + limit: 500 + }); + const fresh = turns.filter((t)=>!previousKeys.has(t.turnKey) && t.role === 'assistant'); + const candidate = fresh.at(-1)?.text ?? ''; + if (candidate && candidate === lastAssistant) { + stable += 1; + if (stable >= 3) { + return { + threadId, + reply: candidate, + backend: 'cdp', + experimental: true, + delivery: 'replied' + }; + } + } else if (candidate) { + lastAssistant = candidate; + stable = 0; + } + } + return { + threadId, + reply: lastAssistant, + backend: 'cdp', + experimental: true, + delivery: lastAssistant ? 'replied' : 'timeout' + }; + } + async openThread(threadId) { + const sessionId = await this.#ensurePageSession(); + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + return { + threadId, + backend: 'cdp' + }; + } + async status() { + try { + const version = this.#version ?? await _cdp_session_js__rspack_import_1.a.fetchVersion(this.#port); + let targetCount; + let mainWindowTargetId; + if (this.#session && !this.#session.closed) { + const targets = await this.listTargets(); + targetCount = targets.length; + mainWindowTargetId = (0, _cdp_dom_js__rspack_import_2.C2)(targets)?.targetId ?? null; + } else { + const list = await _cdp_session_js__rspack_import_1.a.fetchJsonList(this.#port); + targetCount = list.length; + } + return { + reachable: true, + port: this.#port, + host: '127.0.0.1', + browser: typeof version.Browser === 'string' ? version.Browser : undefined, + protocolVersion: typeof version['Protocol-Version'] === 'string' ? version['Protocol-Version'] : undefined, + webSocketDebuggerUrl: typeof version.webSocketDebuggerUrl === 'string' ? version.webSocketDebuggerUrl : undefined, + targetCount, + mainWindowTargetId: mainWindowTargetId ?? this.#mainTargetId, + message: 'ChatGPT Desktop CDP endpoint reachable on 127.0.0.1', + exitCode: 0 + }; + } catch (error) { + return { + reachable: false, + port: this.#port, + host: '127.0.0.1', + message: error instanceof Error ? error.message : 'ChatGPT Desktop CDP endpoint unreachable on 127.0.0.1', + exitCode: 1 + }; + } + } + async close() { + this.#pageSessionId = null; + this.#mainTargetId = null; + this.#version = null; + this.#session?.close(); + this.#session = null; + } + async #attachMainWindow() { + const targets = await this.listTargets(); + const main = (0, _cdp_dom_js__rspack_import_2.C2)(targets); + if (!main) { + throw new _errors_js__rspack_import_0.sO(`No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`); + } + const attached = await this.#requireSession().send('Target.attachToTarget', { + targetId: main.targetId, + flatten: true + }); + this.#mainTargetId = main.targetId; + this.#pageSessionId = attached.sessionId; + } + async #ensurePageSession() { + this.#requireSession(); + if (!this.#pageSessionId) await this.#attachMainWindow(); + if (!this.#pageSessionId) { + throw new _errors_js__rspack_import_0.sO('Failed to attach to ChatGPT Desktop main window'); + } + return this.#pageSessionId; + } + #requireSession() { + if (!this.#session || this.#session.closed) { + throw new _errors_js__rspack_import_0.sO('Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.'); + } + return this.#session; + } + } + function delay(ms) { + return new Promise((resolve)=>setTimeout(resolve, ms)); + } + __webpack_require__.d(__webpack_exports__, { + a: ()=>CdpChatGptDesktopAdapter + }); + }, + "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + const MAIN_WINDOW_URL = 'app://-/index.html'; + const ATTR = { + threadRow: 'data-app-action-sidebar-thread-row', + threadId: 'data-app-action-sidebar-thread-id', + threadTitle: 'data-app-action-sidebar-thread-title', + threadPinned: 'data-app-action-sidebar-thread-pinned', + threadSelected: 'data-app-action-sidebar-thread-selected', + threadKind: 'data-app-action-sidebar-thread-kind', + turnKey: 'data-turn-key', + userBubble: 'data-user-message-bubble', + timelineScroll: 'data-app-action-timeline-scroll', + virtualizedTurn: 'data-virtualized-turn-content' + }; + const SELECTORS = { + threadRow: `[role="button"][${ATTR.threadRow}]`, + turn: `[${ATTR.turnKey}]`, + userBubble: `[${ATTR.userBubble}]`, + timelineScroll: `[${ATTR.timelineScroll}]`, + mainSurface: 'main', + composerCandidates: [ + 'main [contenteditable="true"]', + 'main textarea', + '[data-app-action-composer] [contenteditable="true"]', + '[data-app-action-composer] textarea', + 'form [contenteditable="true"]', + 'form textarea' + ], + sendButtonCandidates: [ + 'button[data-app-action-send]', + 'button[aria-label="Send"]', + 'button[aria-label="Send message"]', + 'main button[type="submit"]' + ] + }; + function isMainWindowTarget(target) { + return target.type === 'page' && target.url === MAIN_WINDOW_URL; + } + function summarizeTargetInfos(targetInfos) { + return targetInfos.filter((t)=>typeof t.targetId === 'string' && typeof t.type === 'string').map((t)=>({ + targetId: String(t.targetId), + type: String(t.type), + title: typeof t.title === 'string' ? t.title : '', + url: typeof t.url === 'string' ? t.url : '', + attached: Boolean(t.attached) + })); + } + function pickMainWindowTarget(targets) { + return targets.find((t)=>isMainWindowTarget(t)) ?? null; + } + const LIST_THREADS_EXPRESSION = `(() => { + const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); + return rows.map((row) => ({ + threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || '', + title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), + pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', + selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', + kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + })).filter((t) => t.threadId); +})()`; + function openThreadExpression(threadId) { + return `(() => { + const id = ${JSON.stringify(threadId)}; + const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); + const row = rows.find((el) => el.getAttribute(${JSON.stringify(ATTR.threadId)}) === id); + if (!row) return { ok: false, error: 'thread-not-found' }; + row.click(); + return { ok: true, threadId: id }; + })()`; + } + const READ_THREAD_EXPRESSION = `(() => { + const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + const mains = Array.from(document.querySelectorAll('main')); + const surface = mains.length >= 2 ? mains[1] : (mains[0] || document.body); + const root = scroll || surface; + const collected = new Map(); + const statusRe = /^Worked for \\d+s$/i; + const harvest = () => { + for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { + const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; + if (!turnKey || collected.has(turnKey)) continue; + const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); + const text = (el.innerText || '').trim(); + let role = 'assistant'; + if (user) role = 'user'; + else if (!text || statusRe.test(text)) role = 'status'; + collected.set(turnKey, { turnKey, role, text }); + } + }; + const maxPasses = 80; + let stable = 0; + let lastSize = -1; + if (scroll) scroll.scrollTop = 0; + for (let i = 0; i < maxPasses; i++) { + harvest(); + if (collected.size === lastSize) { + stable += 1; + if (stable >= 3) break; + } else { + stable = 0; + lastSize = collected.size; + } + if (scroll) { + const next = Math.min(scroll.scrollHeight, scroll.scrollTop + Math.max(scroll.clientHeight, 200)); + if (next <= scroll.scrollTop && stable >= 1) break; + scroll.scrollTop = next; + } else { + break; + } + } + harvest(); + return Array.from(collected.values()); +})()`; + function sendMessageExpression(text) { + const composers = JSON.stringify([ + ...SELECTORS.composerCandidates + ]); + const buttons = JSON.stringify([ + ...SELECTORS.sendButtonCandidates + ]); + return `(() => { + const text = ${JSON.stringify(text)}; + const composers = ${composers}; + let composer = null; + for (const sel of composers) { + composer = document.querySelector(sel); + if (composer) break; + } + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.focus(); + if (composer.isContentEditable) { + composer.textContent = text; + composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: text, inputType: 'insertText' })); + } else if ('value' in composer) { + composer.value = text; + composer.dispatchEvent(new Event('input', { bubbles: true })); + } else { + return { ok: false, error: 'composer-unsupported' }; + } + const buttons = ${buttons}; + let sent = false; + for (const sel of buttons) { + const btn = document.querySelector(sel); + if (btn && !btn.disabled) { btn.click(); sent = true; break; } + } + if (!sent) { + composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true })); + composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', bubbles: true })); + } + return { ok: true, sentVia: sent ? 'button' : 'enter' }; + })()`; + } + async function listThreadsFromDom(session, sessionId, { limit = 50 } = {}) { + const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { + sessionId + }); + if (!Array.isArray(rows)) return []; + return rows.slice(0, limit).map((row)=>({ + threadId: String(row.threadId), + title: String(row.title ?? ''), + pinned: Boolean(row.pinned), + selected: Boolean(row.selected), + kind: String(row.kind ?? 'unknown') + })); + } + async function openThreadInDom(session, sessionId, threadId) { + const result = await session.evaluate(openThreadExpression(threadId), { + sessionId + }); + if (!result?.ok) { + throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); + } + } + async function readTurnsFromDom(session, sessionId, { limit = 100 } = {}) { + const turns = await session.evaluate(READ_THREAD_EXPRESSION, { + sessionId + }); + if (!Array.isArray(turns)) return []; + return turns.slice(-limit).map((turn)=>({ + turnKey: String(turn.turnKey), + role: turn.role === 'user' || turn.role === 'status' ? turn.role : 'assistant', + text: String(turn.text ?? '') + })); + } + async function sendMessageInDom(session, sessionId, text) { + try { + await session.send('Input.insertText', { + text + }, { + sessionId + }); + } catch {} + const result = await session.evaluate(sendMessageExpression(text), { + sessionId + }); + if (!result?.ok) { + throw new Error(result?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${result?.error ?? 'unknown'}`); + } + return { + sentVia: result.sentVia ?? 'unknown' + }; + } + __webpack_require__.d(__webpack_exports__, { + AY: ()=>listThreadsFromDom, + C2: ()=>pickMainWindowTarget, + JU: ()=>readTurnsFromDom, + Kl: ()=>openThreadInDom, + Mr: ()=>summarizeTargetInfos, + lh: ()=>sendMessageInDom + }); + }, + "./src/core/chatgpt-desktop/cdp-session.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _loopback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + class CdpSession { + #port; + #ws = null; + #nextId = 1; + #pending = new Map(); + #closed = false; + constructor(port){ + this.#port = port; + } + get port() { + return this.#port; + } + get closed() { + return this.#closed || this.#ws === null || this.#ws.readyState === WebSocket.CLOSED; + } + static async fetchVersion(port, { signal } = {}) { + const base = (0, _loopback_js__rspack_import_1.NJ)(port); + let response; + try { + response = await fetch(`${base}/json/version`, { + signal + }); + } catch (error) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/version: ` + (error instanceof Error ? error.message : String(error))); + } + if (!response.ok) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP /json/version returned HTTP ${response.status}`); + } + return await response.json(); + } + static async fetchJsonList(port, { signal } = {}) { + const base = (0, _loopback_js__rspack_import_1.NJ)(port); + let response; + try { + response = await fetch(`${base}/json/list`, { + signal + }); + } catch (error) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/list: ` + (error instanceof Error ? error.message : String(error))); + } + if (!response.ok) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP /json/list returned HTTP ${response.status}`); + } + const body = await response.json(); + return Array.isArray(body) ? body : []; + } + async connect({ signal } = {}) { + if (this.#ws && !this.closed) { + throw new Error('CDP session already connected'); + } + const version = await CdpSession.fetchVersion(this.#port, { + signal + }); + const rawUrl = version.webSocketDebuggerUrl; + if (typeof rawUrl !== 'string' || !rawUrl) { + throw new _errors_js__rspack_import_0.sO('CDP /json/version omitted webSocketDebuggerUrl'); + } + const url = (0, _loopback_js__rspack_import_1.jv)(rawUrl); + const parsed = new URL(url); + (0, _loopback_js__rspack_import_1.tb)(parsed.hostname); + await new Promise((resolve, reject)=>{ + const ws = new WebSocket(url); + this.#ws = ws; + const onAbort = ()=>{ + ws.close(); + reject(new Error('CDP connect aborted')); + }; + signal?.addEventListener('abort', onAbort, { + once: true + }); + ws.addEventListener('open', ()=>{ + signal?.removeEventListener('abort', onAbort); + resolve(); + }, { + once: true + }); + ws.addEventListener('error', ()=>{ + signal?.removeEventListener('abort', onAbort); + reject(new _errors_js__rspack_import_0.sO(`CDP WebSocket failed for ${url}`)); + }, { + once: true + }); + ws.addEventListener('message', (event)=>this.#onMessage(event.data)); + ws.addEventListener('close', ()=>{ + this.#closed = true; + for (const [, pending] of this.#pending){ + pending.reject(new Error('CDP WebSocket closed')); + } + this.#pending.clear(); + }); + }); + this.#closed = false; + return version; + } + async send(method, params, { sessionId } = {}) { + if (!this.#ws || this.#ws.readyState !== WebSocket.OPEN) { + throw new _errors_js__rspack_import_0.sO('CDP session is not connected'); + } + const id = this.#nextId++; + const payload = { + id, + method + }; + if (params !== undefined) payload.params = params; + if (sessionId !== undefined) payload.sessionId = sessionId; + return await new Promise((resolve, reject)=>{ + this.#pending.set(id, { + resolve: (value)=>resolve(value), + reject + }); + this.#ws.send(JSON.stringify(payload)); + }); + } + async evaluate(expression, { sessionId, awaitPromise = true } = {}) { + const result = await this.send('Runtime.evaluate', { + expression, + returnByValue: true, + awaitPromise + }, { + sessionId + }); + if (result.exceptionDetails) { + const text = result.exceptionDetails.exception?.description || result.exceptionDetails.text || 'Runtime.evaluate failed'; + throw new Error(text); + } + return result.result?.value; + } + close() { + this.#closed = true; + this.#ws?.close(); + this.#ws = null; + } + #onMessage(data) { + let message; + try { + message = JSON.parse(String(data)); + } catch { + return; + } + if (typeof message.id !== 'number') return; + const pending = this.#pending.get(message.id); + if (!pending) return; + this.#pending.delete(message.id); + if (message.error) { + pending.reject(new Error(message.error.message || 'CDP error')); + return; + } + pending.resolve(message.result); + } + } + __webpack_require__.d(__webpack_exports__, { + a: ()=>CdpSession + }); + }, + "./src/core/chatgpt-desktop/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + class NotImplementedError extends Error { + code = 'NOT_IMPLEMENTED'; + delivery = 'rejected'; + reason = 'not-implemented'; + constructor(operation, detail){ + super(detail ? `ChatGPT Desktop ${operation} is not implemented: ${detail}` : `ChatGPT Desktop ${operation} is not implemented`); + this.name = 'NotImplementedError'; + } + } + class CdpHostRejectedError extends Error { + code = 'CDP_HOST_REJECTED'; + delivery = 'rejected'; + reason = 'cdp-host-rejected'; + constructor(host){ + super(`ChatGPT Desktop CDP rejects non-loopback host ${JSON.stringify(host)}. ` + 'Connect to 127.0.0.1 only; there is no remote transport.'); + this.name = 'CdpHostRejectedError'; + } + } + class CdpUnreachableError extends Error { + code = 'CDP_UNREACHABLE'; + delivery = 'rejected'; + reason = 'cdp-unreachable'; + constructor(message){ + super(message); + this.name = 'CdpUnreachableError'; + } + } + __webpack_require__.d(__webpack_exports__, { + EH: ()=>NotImplementedError, + c$: ()=>CdpHostRejectedError, + sO: ()=>CdpUnreachableError + }); + }, + "./src/core/chatgpt-desktop/facade.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _cdp_adapter_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-adapter.ts"); + var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); + var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + class ChatGptDesktopFacade { + #cdp; + #port; + #cdpConnected = false; + constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)()){ + this.#cdp = cdp; + this.#port = port; + } + async connect({ port }) { + this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + try { + await this.#cdp.connect({ + port: this.#port + }); + this.#cdpConnected = true; + } catch (error) { + this.#cdpConnected = false; + throw error; + } + } + async listTargets() { + await this.#ensureCdp(); + return this.#cdp.listTargets(); + } + async listThreads(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.listThreads(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.OI)(options); + } + } + async readThread(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.readThread(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.Jf)(options); + } + } + async sendMessage(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.sendMessage(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.Ab)(options); + } + } + async waitForReply(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.waitForReply(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.bk)(options); + } + } + async openThread(threadId) { + try { + await this.#ensureCdp(); + return await this.#cdp.openThread(threadId); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.zu)(threadId); + } + } + async status() { + const cdpStatus = await this.#cdp.status(); + let appServerFallback; + try { + appServerFallback = await (0, _app_server_fallback_js__rspack_import_1.dM)(); + } catch { + appServerFallback = { + reachable: false + }; + } + const reachable = cdpStatus.reachable || Boolean(appServerFallback?.reachable); + return { + ...cdpStatus, + port: this.#port, + appServerFallback, + reachable, + message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server fallback is available' : cdpStatus.message, + exitCode: reachable ? 0 : 1 + }; + } + async close() { + this.#cdpConnected = false; + await this.#cdp.close(); + } + async #ensureCdp() { + if (this.#cdpConnected) return; + await this.#cdp.connect({ + port: this.#port + }); + this.#cdpConnected = true; + } + } + function isCdpFailure(error) { + if (error instanceof _errors_js__rspack_import_2.sO) return true; + if (error instanceof _errors_js__rspack_import_2.EH) return false; + if (error && typeof error === 'object' && 'code' in error) { + const code = String(error.code); + return code === 'CDP_UNREACHABLE' || code === 'CDP_HOST_REJECTED'; + } + return false; + } + let activeAdapter = null; + function getChatGptDesktopAdapter() { + if (!activeAdapter) activeAdapter = new ChatGptDesktopFacade(); + return activeAdapter; + } + function setChatGptDesktopAdapterForTests(adapter) { + activeAdapter = adapter; + } + __webpack_require__.d(__webpack_exports__, { + PP: ()=>getChatGptDesktopAdapter + }); + }, + "./src/core/chatgpt-desktop/loopback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + const LOOPBACK = new Set([ + '127.0.0.1', + 'localhost', + '::1' + ]); + const DEFAULT_CDP_PORT = 9222; + const CDP_LOOPBACK_HOST = '127.0.0.1'; + function isLoopbackHostname(hostname) { + const host = String(hostname || '').toLowerCase().replace(/^\[|\]$/g, ''); + return LOOPBACK.has(host); + } + function assertLoopbackHostname(hostname) { + if (!isLoopbackHostname(hostname)) { + throw new _errors_js__rspack_import_0.c$(hostname); + } + } + function cdpHttpBase(port) { + if (!Number.isInteger(port) || port < 1 || port > 65535) { + throw new RangeError('CDP port must be an integer 1-65535'); + } + return `http://${CDP_LOOPBACK_HOST}:${port}`; + } + function forceLoopbackWebSocketUrl(raw) { + let url; + try { + url = new URL(raw); + } catch { + throw new _errors_js__rspack_import_0.c$(String(raw)); + } + assertLoopbackHostname(url.hostname); + if (url.protocol !== 'ws:' && url.protocol !== 'wss:') { + throw new Error(`Expected ws(s) debugger URL, got ${url.protocol}`); + } + url.hostname = CDP_LOOPBACK_HOST; + url.protocol = 'ws:'; + return url.toString(); + } + function resolveCdpPort(env = process.env, explicit) { + if (explicit !== undefined) { + if (!Number.isInteger(explicit) || explicit < 1 || explicit > 65535) { + throw new RangeError('CDP port must be an integer 1-65535'); + } + return explicit; + } + const raw = (env.CHATGPT_DESKTOP_CDP_PORT || '').trim(); + if (!raw) return DEFAULT_CDP_PORT; + const port = Number.parseInt(raw, 10); + if (!Number.isInteger(port) || port < 1 || port > 65535) { + throw new RangeError('CHATGPT_DESKTOP_CDP_PORT must be an integer 1-65535'); + } + return port; + } + __webpack_require__.d(__webpack_exports__, { + L0: ()=>resolveCdpPort, + NJ: ()=>cdpHttpBase, + jv: ()=>forceLoopbackWebSocketUrl, + tb: ()=>assertLoopbackHostname + }); + }, + "./src/core/chatgpt-desktop/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var zod__rspack_import_4 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _codex_contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); + var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _facade_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/facade.ts"); + var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + const threadId = zod__rspack_import_4.YjP().min(1).max(256); + const statusSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional() + }).strict(); + const listThreadsSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + }).strict(); + const readThreadSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId, + limit: zod__rspack_import_4.aig().int().min(1).max(500).default(100) + }).strict(); + const sendSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId: threadId.optional(), + text: zod__rspack_import_4.YjP().min(1).max(100000) + }).strict(); + const waitReplySchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId, + timeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(60000) + }).strict(); + const resultSchema = zod__rspack_import_4.Ikc({ + exitCode: zod__rspack_import_4.KCZ([ + zod__rspack_import_4.euz(0), + zod__rspack_import_4.euz(1) + ]) + }).catchall(zod__rspack_import_4.Pq9()); + async function withAdapter(port, run) { + const adapter = (0, _facade_js__rspack_import_2.PP)(); + const resolved = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + try { + await adapter.connect({ + port: resolved + }); + } catch {} + return run(adapter); + } + function asResult(value) { + return resultSchema.parse(value); + } + function mapError(error) { + if (error instanceof _errors_js__rspack_import_1.EH) { + return asResult({ + delivery: 'rejected', + reason: 'not-implemented', + code: 'NOT_IMPLEMENTED', + error: error.message, + exitCode: 1 }); } - const out = await backend.transcript(input.target, input.limit); - if (input.after !== undefined) { - const delta = (0, _core_transcript_js__rspack_import_6.N3)(out.transcript, { - after: input.after, - limit: input.limit + const base = (0, _codex_contract_js__rspack_import_0.DG)(error); + if (error && typeof error === 'object' && 'code' in error) { + return asResult({ + ...base, + code: String(error.code) }); - const selected = { + } + return asResult(base); + } + async function statusOperation(input) { + try { + const status = await withAdapter(input.port, (adapter)=>adapter.status()); + return asResult(status); + } catch (error) { + return mapError(error); + } + } + async function listThreadsOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ + limit: input.limit + })); + return asResult({ ...out, - transcript: { - entries: delta.entries - }, - cursor: delta.cursor, - entryCount: delta.entryCount, - gapReset: delta.gapReset - }; - (0, _core_history_js__rspack_import_1.QX)(selected, { - dir: input.historyDir, - disabled: input.noHistory, - event: 'thread' + exitCode: 0 }); - const text = (0, _core_format_js__rspack_import_5.oZ)(selected, { - full: input.full + } catch (error) { + return mapError(error); + } + } + async function readThreadOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ + threadId: input.threadId, + limit: input.limit + })); + return asResult({ + ...out, + exitCode: 0 }); - return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Result, { - value: selected, - children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Text, { - children: `${text}\n\ncursor: ${delta.cursor}${delta.gapReset ? ' (gap reset)' : ''}` - }) + } catch (error) { + return mapError(error); + } + } + async function sendOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.sendMessage({ + threadId: input.threadId, + text: input.text + })); + return asResult({ + ...out, + exitCode: out.delivery === 'accepted' ? 0 : 1 }); + } catch (error) { + return mapError(error); } - (0, _core_history_js__rspack_import_1.QX)(out, { - dir: input.historyDir, - disabled: input.noHistory, - event: 'thread' - }); - return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Result, { - value: out, - children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_4.g.Text, { - children: (0, _core_format_js__rspack_import_5.oZ)(out, { - full: input.full - }) - }) - }); + } + async function waitReplyOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.waitForReply({ + threadId: input.threadId, + timeoutMs: input.timeoutMs + })); + return asResult({ + ...out, + exitCode: out.delivery === 'replied' ? 0 : 1 + }); + } catch (error) { + return mapError(error); + } + } + function resultText(result) { + if (result.error) return String(result.error); + if (result.reachable === true) { + const backend = result.appServerFallback && typeof result.appServerFallback === 'object' ? ` cdp + app-server probe` : ''; + return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; + } + if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); + if (Array.isArray(result.threads)) { + return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; + } + if (Array.isArray(result.turns)) { + return `${result.turns.length} turns on ${result.threadId} via ${result.backend ?? 'unknown'}`; + } + if (result.delivery === 'accepted') { + return `Sent on ${result.threadId} via ${result.backend}${result.experimental ? ' (experimental)' : ''}`; + } + if (result.delivery === 'replied') { + return String(result.reply ?? 'replied'); + } + if (result.delivery) return `delivery ${result.delivery}`; + return JSON.stringify(result); } __webpack_require__.d(__webpack_exports__, { - "default": ()=>thread + D6: ()=>resultText, + UK: ()=>readThreadOperation, + UP: ()=>sendOperation, + Uj: ()=>statusOperation, + tJ: ()=>listThreadsOperation }, { - config: config, - inputSchema: inputSchema, - resultSchema: resultSchema + FD: resultSchema }); }, "./src/core/claude-routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -36935,9 +38244,9 @@ var __webpack_modules__ = { try { var agent_bundle_launch_env_layer__rspack_import_0 = __webpack_require__("./.agent-bundle-virtual/bin-gbot-0.mjs"); var agent_bundle_cli_entry__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/cli-entry.js"); - var _agent_bundle_runtime__rspack_import_40 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); - var _agent_bundle_runtime__rspack_import_41 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); - var _agent_bundle_runtime__rspack_import_42 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/index.js"); + var _agent_bundle_runtime__rspack_import_44 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); + var _agent_bundle_runtime__rspack_import_45 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); + var _agent_bundle_runtime__rspack_import_46 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/index.js"); var node_url__rspack_import_2 = __webpack_require__("node:url"); var node_worker_threads__rspack_import_3 = __webpack_require__("node:worker_threads"); var _src_cli_approvals_list_tsx__rspack_import_4 = __webpack_require__("./src/cli/approvals/list.tsx"); @@ -36947,35 +38256,39 @@ var __webpack_modules__ = { var _src_cli_bots_get_tsx__rspack_import_8 = __webpack_require__("./src/cli/bots/get.tsx"); var _src_cli_bots_list_tsx__rspack_import_9 = __webpack_require__("./src/cli/bots/list.tsx"); var _src_cli_bots_update_tsx__rspack_import_10 = __webpack_require__("./src/cli/bots/update.tsx"); - var _src_cli_claude_send_tsx__rspack_import_11 = __webpack_require__("./src/cli/claude/send.tsx"); - var _src_cli_codex_bridge_respond_tsx__rspack_import_12 = __webpack_require__("./src/cli/codex/bridge/respond.tsx"); - var _src_cli_codex_bridge_run_tsx__rspack_import_13 = __webpack_require__("./src/cli/codex/bridge/run.tsx"); - var _src_cli_codex_bridge_start_tsx__rspack_import_14 = __webpack_require__("./src/cli/codex/bridge/start.tsx"); - var _src_cli_codex_bridge_status_tsx__rspack_import_15 = __webpack_require__("./src/cli/codex/bridge/status.tsx"); - var _src_cli_codex_bridge_stop_tsx__rspack_import_16 = __webpack_require__("./src/cli/codex/bridge/stop.tsx"); - var _src_cli_codex_desktop_shim_tsx__rspack_import_17 = __webpack_require__("./src/cli/codex/desktop-shim.tsx"); - var _src_cli_codex_list_threads_tsx__rspack_import_18 = __webpack_require__("./src/cli/codex/list-threads.tsx"); - var _src_cli_codex_queue_tsx__rspack_import_19 = __webpack_require__("./src/cli/codex/queue.tsx"); - var _src_cli_codex_send_tsx__rspack_import_20 = __webpack_require__("./src/cli/codex/send.tsx"); - var _src_cli_codex_status_tsx__rspack_import_21 = __webpack_require__("./src/cli/codex/status.tsx"); - var _src_cli_codex_wait_tsx__rspack_import_22 = __webpack_require__("./src/cli/codex/wait.tsx"); - var _src_cli_codex_watch_tsx__rspack_import_23 = __webpack_require__("./src/cli/codex/watch.tsx"); - var _src_cli_doctor_tsx__rspack_import_24 = __webpack_require__("./src/cli/doctor.tsx"); - var _src_cli_groups_add_tsx__rspack_import_25 = __webpack_require__("./src/cli/groups/add.tsx"); - var _src_cli_groups_create_tsx__rspack_import_26 = __webpack_require__("./src/cli/groups/create.tsx"); - var _src_cli_groups_delete_tsx__rspack_import_27 = __webpack_require__("./src/cli/groups/delete.tsx"); - var _src_cli_groups_get_tsx__rspack_import_28 = __webpack_require__("./src/cli/groups/get.tsx"); - var _src_cli_groups_list_tsx__rspack_import_29 = __webpack_require__("./src/cli/groups/list.tsx"); - var _src_cli_groups_members_tsx__rspack_import_30 = __webpack_require__("./src/cli/groups/members.tsx"); - var _src_cli_groups_remove_tsx__rspack_import_31 = __webpack_require__("./src/cli/groups/remove.tsx"); - var _src_cli_groups_set_tsx__rspack_import_32 = __webpack_require__("./src/cli/groups/set.tsx"); - var _src_cli_groups_update_tsx__rspack_import_33 = __webpack_require__("./src/cli/groups/update.tsx"); - var _src_cli_history_tsx__rspack_import_34 = __webpack_require__("./src/cli/history.tsx"); - var _src_cli_send_tsx__rspack_import_35 = __webpack_require__("./src/cli/send.tsx"); - var _src_cli_skills_add_tsx__rspack_import_36 = __webpack_require__("./src/cli/skills/add.tsx"); - var _src_cli_skills_list_tsx__rspack_import_37 = __webpack_require__("./src/cli/skills/list.tsx"); - var _src_cli_skills_remove_tsx__rspack_import_38 = __webpack_require__("./src/cli/skills/remove.tsx"); - var _src_cli_thread_tsx__rspack_import_39 = __webpack_require__("./src/cli/thread.tsx"); + var _src_cli_chatgpt_desktop_read_tsx__rspack_import_11 = __webpack_require__("./src/cli/chatgpt-desktop/read.tsx"); + var _src_cli_chatgpt_desktop_send_tsx__rspack_import_12 = __webpack_require__("./src/cli/chatgpt-desktop/send.tsx"); + var _src_cli_chatgpt_desktop_status_tsx__rspack_import_13 = __webpack_require__("./src/cli/chatgpt-desktop/status.tsx"); + var _src_cli_chatgpt_desktop_threads_tsx__rspack_import_14 = __webpack_require__("./src/cli/chatgpt-desktop/threads.tsx"); + var _src_cli_claude_send_tsx__rspack_import_15 = __webpack_require__("./src/cli/claude/send.tsx"); + var _src_cli_codex_bridge_respond_tsx__rspack_import_16 = __webpack_require__("./src/cli/codex/bridge/respond.tsx"); + var _src_cli_codex_bridge_run_tsx__rspack_import_17 = __webpack_require__("./src/cli/codex/bridge/run.tsx"); + var _src_cli_codex_bridge_start_tsx__rspack_import_18 = __webpack_require__("./src/cli/codex/bridge/start.tsx"); + var _src_cli_codex_bridge_status_tsx__rspack_import_19 = __webpack_require__("./src/cli/codex/bridge/status.tsx"); + var _src_cli_codex_bridge_stop_tsx__rspack_import_20 = __webpack_require__("./src/cli/codex/bridge/stop.tsx"); + var _src_cli_codex_desktop_shim_tsx__rspack_import_21 = __webpack_require__("./src/cli/codex/desktop-shim.tsx"); + var _src_cli_codex_list_threads_tsx__rspack_import_22 = __webpack_require__("./src/cli/codex/list-threads.tsx"); + var _src_cli_codex_queue_tsx__rspack_import_23 = __webpack_require__("./src/cli/codex/queue.tsx"); + var _src_cli_codex_send_tsx__rspack_import_24 = __webpack_require__("./src/cli/codex/send.tsx"); + var _src_cli_codex_status_tsx__rspack_import_25 = __webpack_require__("./src/cli/codex/status.tsx"); + var _src_cli_codex_wait_tsx__rspack_import_26 = __webpack_require__("./src/cli/codex/wait.tsx"); + var _src_cli_codex_watch_tsx__rspack_import_27 = __webpack_require__("./src/cli/codex/watch.tsx"); + var _src_cli_doctor_tsx__rspack_import_28 = __webpack_require__("./src/cli/doctor.tsx"); + var _src_cli_groups_add_tsx__rspack_import_29 = __webpack_require__("./src/cli/groups/add.tsx"); + var _src_cli_groups_create_tsx__rspack_import_30 = __webpack_require__("./src/cli/groups/create.tsx"); + var _src_cli_groups_delete_tsx__rspack_import_31 = __webpack_require__("./src/cli/groups/delete.tsx"); + var _src_cli_groups_get_tsx__rspack_import_32 = __webpack_require__("./src/cli/groups/get.tsx"); + var _src_cli_groups_list_tsx__rspack_import_33 = __webpack_require__("./src/cli/groups/list.tsx"); + var _src_cli_groups_members_tsx__rspack_import_34 = __webpack_require__("./src/cli/groups/members.tsx"); + var _src_cli_groups_remove_tsx__rspack_import_35 = __webpack_require__("./src/cli/groups/remove.tsx"); + var _src_cli_groups_set_tsx__rspack_import_36 = __webpack_require__("./src/cli/groups/set.tsx"); + var _src_cli_groups_update_tsx__rspack_import_37 = __webpack_require__("./src/cli/groups/update.tsx"); + var _src_cli_history_tsx__rspack_import_38 = __webpack_require__("./src/cli/history.tsx"); + var _src_cli_send_tsx__rspack_import_39 = __webpack_require__("./src/cli/send.tsx"); + var _src_cli_skills_add_tsx__rspack_import_40 = __webpack_require__("./src/cli/skills/add.tsx"); + var _src_cli_skills_list_tsx__rspack_import_41 = __webpack_require__("./src/cli/skills/list.tsx"); + var _src_cli_skills_remove_tsx__rspack_import_42 = __webpack_require__("./src/cli/skills/remove.tsx"); + var _src_cli_thread_tsx__rspack_import_43 = __webpack_require__("./src/cli/thread.tsx"); const route0 = Object.assign({}, Reflect.get(_src_cli_approvals_list_tsx__rspack_import_4, 'default'), _src_cli_approvals_list_tsx__rspack_import_4); const route1 = Object.assign({}, Reflect.get(_src_cli_approvals_respond_tsx__rspack_import_5, 'default'), _src_cli_approvals_respond_tsx__rspack_import_5); const route2 = Object.assign({}, Reflect.get(_src_cli_bots_create_tsx__rspack_import_6, 'default'), _src_cli_bots_create_tsx__rspack_import_6); @@ -36983,36 +38296,40 @@ var __webpack_modules__ = { const route4 = Object.assign({}, Reflect.get(_src_cli_bots_get_tsx__rspack_import_8, 'default'), _src_cli_bots_get_tsx__rspack_import_8); const route5 = Object.assign({}, Reflect.get(_src_cli_bots_list_tsx__rspack_import_9, 'default'), _src_cli_bots_list_tsx__rspack_import_9); const route6 = Object.assign({}, Reflect.get(_src_cli_bots_update_tsx__rspack_import_10, 'default'), _src_cli_bots_update_tsx__rspack_import_10); - const route7 = Object.assign({}, Reflect.get(_src_cli_claude_send_tsx__rspack_import_11, 'default'), _src_cli_claude_send_tsx__rspack_import_11); - const route8 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_respond_tsx__rspack_import_12, 'default'), _src_cli_codex_bridge_respond_tsx__rspack_import_12); - const route9 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_run_tsx__rspack_import_13, 'default'), _src_cli_codex_bridge_run_tsx__rspack_import_13); - const route10 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_start_tsx__rspack_import_14, 'default'), _src_cli_codex_bridge_start_tsx__rspack_import_14); - const route11 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_status_tsx__rspack_import_15, 'default'), _src_cli_codex_bridge_status_tsx__rspack_import_15); - const route12 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_stop_tsx__rspack_import_16, 'default'), _src_cli_codex_bridge_stop_tsx__rspack_import_16); - const route13 = Object.assign({}, Reflect.get(_src_cli_codex_desktop_shim_tsx__rspack_import_17, 'default'), _src_cli_codex_desktop_shim_tsx__rspack_import_17); - const route14 = Object.assign({}, Reflect.get(_src_cli_codex_list_threads_tsx__rspack_import_18, 'default'), _src_cli_codex_list_threads_tsx__rspack_import_18); - const route15 = Object.assign({}, Reflect.get(_src_cli_codex_queue_tsx__rspack_import_19, 'default'), _src_cli_codex_queue_tsx__rspack_import_19); - const route16 = Object.assign({}, Reflect.get(_src_cli_codex_send_tsx__rspack_import_20, 'default'), _src_cli_codex_send_tsx__rspack_import_20); - const route17 = Object.assign({}, Reflect.get(_src_cli_codex_status_tsx__rspack_import_21, 'default'), _src_cli_codex_status_tsx__rspack_import_21); - const route18 = Object.assign({}, Reflect.get(_src_cli_codex_wait_tsx__rspack_import_22, 'default'), _src_cli_codex_wait_tsx__rspack_import_22); - const route19 = Object.assign({}, Reflect.get(_src_cli_codex_watch_tsx__rspack_import_23, 'default'), _src_cli_codex_watch_tsx__rspack_import_23); - const route20 = Object.assign({}, Reflect.get(_src_cli_doctor_tsx__rspack_import_24, 'default'), _src_cli_doctor_tsx__rspack_import_24); - const route21 = Object.assign({}, Reflect.get(_src_cli_groups_add_tsx__rspack_import_25, 'default'), _src_cli_groups_add_tsx__rspack_import_25); - const route22 = Object.assign({}, Reflect.get(_src_cli_groups_create_tsx__rspack_import_26, 'default'), _src_cli_groups_create_tsx__rspack_import_26); - const route23 = Object.assign({}, Reflect.get(_src_cli_groups_delete_tsx__rspack_import_27, 'default'), _src_cli_groups_delete_tsx__rspack_import_27); - const route24 = Object.assign({}, Reflect.get(_src_cli_groups_get_tsx__rspack_import_28, 'default'), _src_cli_groups_get_tsx__rspack_import_28); - const route25 = Object.assign({}, Reflect.get(_src_cli_groups_list_tsx__rspack_import_29, 'default'), _src_cli_groups_list_tsx__rspack_import_29); - const route26 = Object.assign({}, Reflect.get(_src_cli_groups_members_tsx__rspack_import_30, 'default'), _src_cli_groups_members_tsx__rspack_import_30); - const route27 = Object.assign({}, Reflect.get(_src_cli_groups_remove_tsx__rspack_import_31, 'default'), _src_cli_groups_remove_tsx__rspack_import_31); - const route28 = Object.assign({}, Reflect.get(_src_cli_groups_set_tsx__rspack_import_32, 'default'), _src_cli_groups_set_tsx__rspack_import_32); - const route29 = Object.assign({}, Reflect.get(_src_cli_groups_update_tsx__rspack_import_33, 'default'), _src_cli_groups_update_tsx__rspack_import_33); - const route30 = Object.assign({}, Reflect.get(_src_cli_history_tsx__rspack_import_34, 'default'), _src_cli_history_tsx__rspack_import_34); - const route31 = Object.assign({}, Reflect.get(_src_cli_send_tsx__rspack_import_35, 'default'), _src_cli_send_tsx__rspack_import_35); - const route32 = Object.assign({}, Reflect.get(_src_cli_skills_add_tsx__rspack_import_36, 'default'), _src_cli_skills_add_tsx__rspack_import_36); - const route33 = Object.assign({}, Reflect.get(_src_cli_skills_list_tsx__rspack_import_37, 'default'), _src_cli_skills_list_tsx__rspack_import_37); - const route34 = Object.assign({}, Reflect.get(_src_cli_skills_remove_tsx__rspack_import_38, 'default'), _src_cli_skills_remove_tsx__rspack_import_38); - const route35 = Object.assign({}, Reflect.get(_src_cli_thread_tsx__rspack_import_39, 'default'), _src_cli_thread_tsx__rspack_import_39); - const pluginRoot = (0, _agent_bundle_runtime__rspack_import_40.E7)({ + const route7 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_read_tsx__rspack_import_11, 'default'), _src_cli_chatgpt_desktop_read_tsx__rspack_import_11); + const route8 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_send_tsx__rspack_import_12, 'default'), _src_cli_chatgpt_desktop_send_tsx__rspack_import_12); + const route9 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_status_tsx__rspack_import_13, 'default'), _src_cli_chatgpt_desktop_status_tsx__rspack_import_13); + const route10 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_threads_tsx__rspack_import_14, 'default'), _src_cli_chatgpt_desktop_threads_tsx__rspack_import_14); + const route11 = Object.assign({}, Reflect.get(_src_cli_claude_send_tsx__rspack_import_15, 'default'), _src_cli_claude_send_tsx__rspack_import_15); + const route12 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_respond_tsx__rspack_import_16, 'default'), _src_cli_codex_bridge_respond_tsx__rspack_import_16); + const route13 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_run_tsx__rspack_import_17, 'default'), _src_cli_codex_bridge_run_tsx__rspack_import_17); + const route14 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_start_tsx__rspack_import_18, 'default'), _src_cli_codex_bridge_start_tsx__rspack_import_18); + const route15 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_status_tsx__rspack_import_19, 'default'), _src_cli_codex_bridge_status_tsx__rspack_import_19); + const route16 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_stop_tsx__rspack_import_20, 'default'), _src_cli_codex_bridge_stop_tsx__rspack_import_20); + const route17 = Object.assign({}, Reflect.get(_src_cli_codex_desktop_shim_tsx__rspack_import_21, 'default'), _src_cli_codex_desktop_shim_tsx__rspack_import_21); + const route18 = Object.assign({}, Reflect.get(_src_cli_codex_list_threads_tsx__rspack_import_22, 'default'), _src_cli_codex_list_threads_tsx__rspack_import_22); + const route19 = Object.assign({}, Reflect.get(_src_cli_codex_queue_tsx__rspack_import_23, 'default'), _src_cli_codex_queue_tsx__rspack_import_23); + const route20 = Object.assign({}, Reflect.get(_src_cli_codex_send_tsx__rspack_import_24, 'default'), _src_cli_codex_send_tsx__rspack_import_24); + const route21 = Object.assign({}, Reflect.get(_src_cli_codex_status_tsx__rspack_import_25, 'default'), _src_cli_codex_status_tsx__rspack_import_25); + const route22 = Object.assign({}, Reflect.get(_src_cli_codex_wait_tsx__rspack_import_26, 'default'), _src_cli_codex_wait_tsx__rspack_import_26); + const route23 = Object.assign({}, Reflect.get(_src_cli_codex_watch_tsx__rspack_import_27, 'default'), _src_cli_codex_watch_tsx__rspack_import_27); + const route24 = Object.assign({}, Reflect.get(_src_cli_doctor_tsx__rspack_import_28, 'default'), _src_cli_doctor_tsx__rspack_import_28); + const route25 = Object.assign({}, Reflect.get(_src_cli_groups_add_tsx__rspack_import_29, 'default'), _src_cli_groups_add_tsx__rspack_import_29); + const route26 = Object.assign({}, Reflect.get(_src_cli_groups_create_tsx__rspack_import_30, 'default'), _src_cli_groups_create_tsx__rspack_import_30); + const route27 = Object.assign({}, Reflect.get(_src_cli_groups_delete_tsx__rspack_import_31, 'default'), _src_cli_groups_delete_tsx__rspack_import_31); + const route28 = Object.assign({}, Reflect.get(_src_cli_groups_get_tsx__rspack_import_32, 'default'), _src_cli_groups_get_tsx__rspack_import_32); + const route29 = Object.assign({}, Reflect.get(_src_cli_groups_list_tsx__rspack_import_33, 'default'), _src_cli_groups_list_tsx__rspack_import_33); + const route30 = Object.assign({}, Reflect.get(_src_cli_groups_members_tsx__rspack_import_34, 'default'), _src_cli_groups_members_tsx__rspack_import_34); + const route31 = Object.assign({}, Reflect.get(_src_cli_groups_remove_tsx__rspack_import_35, 'default'), _src_cli_groups_remove_tsx__rspack_import_35); + const route32 = Object.assign({}, Reflect.get(_src_cli_groups_set_tsx__rspack_import_36, 'default'), _src_cli_groups_set_tsx__rspack_import_36); + const route33 = Object.assign({}, Reflect.get(_src_cli_groups_update_tsx__rspack_import_37, 'default'), _src_cli_groups_update_tsx__rspack_import_37); + const route34 = Object.assign({}, Reflect.get(_src_cli_history_tsx__rspack_import_38, 'default'), _src_cli_history_tsx__rspack_import_38); + const route35 = Object.assign({}, Reflect.get(_src_cli_send_tsx__rspack_import_39, 'default'), _src_cli_send_tsx__rspack_import_39); + const route36 = Object.assign({}, Reflect.get(_src_cli_skills_add_tsx__rspack_import_40, 'default'), _src_cli_skills_add_tsx__rspack_import_40); + const route37 = Object.assign({}, Reflect.get(_src_cli_skills_list_tsx__rspack_import_41, 'default'), _src_cli_skills_list_tsx__rspack_import_41); + const route38 = Object.assign({}, Reflect.get(_src_cli_skills_remove_tsx__rspack_import_42, 'default'), _src_cli_skills_remove_tsx__rspack_import_42); + const route39 = Object.assign({}, Reflect.get(_src_cli_thread_tsx__rspack_import_43, 'default'), _src_cli_thread_tsx__rspack_import_43); + const pluginRoot = (0, _agent_bundle_runtime__rspack_import_44.E7)({ fallback: (0, node_url__rspack_import_2.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); @@ -37043,92 +38360,104 @@ var __webpack_modules__ = { "cli:bots/update": Object.freeze({ module: route6 }), - "cli:claude/send": Object.freeze({ + "cli:chatgpt-desktop/read": Object.freeze({ module: route7 }), - "cli:codex/bridge/respond": Object.freeze({ + "cli:chatgpt-desktop/send": Object.freeze({ module: route8 }), - "cli:codex/bridge/run": Object.freeze({ + "cli:chatgpt-desktop/status": Object.freeze({ module: route9 }), - "cli:codex/bridge/start": Object.freeze({ + "cli:chatgpt-desktop/threads": Object.freeze({ module: route10 }), - "cli:codex/bridge/status": Object.freeze({ + "cli:claude/send": Object.freeze({ module: route11 }), - "cli:codex/bridge/stop": Object.freeze({ + "cli:codex/bridge/respond": Object.freeze({ module: route12 }), - "cli:codex/desktop-shim": Object.freeze({ + "cli:codex/bridge/run": Object.freeze({ module: route13 }), - "cli:codex/list-threads": Object.freeze({ + "cli:codex/bridge/start": Object.freeze({ module: route14 }), - "cli:codex/queue": Object.freeze({ + "cli:codex/bridge/status": Object.freeze({ module: route15 }), - "cli:codex/send": Object.freeze({ + "cli:codex/bridge/stop": Object.freeze({ module: route16 }), - "cli:codex/status": Object.freeze({ + "cli:codex/desktop-shim": Object.freeze({ module: route17 }), - "cli:codex/wait": Object.freeze({ + "cli:codex/list-threads": Object.freeze({ module: route18 }), - "cli:codex/watch": Object.freeze({ + "cli:codex/queue": Object.freeze({ module: route19 }), - "cli:doctor": Object.freeze({ + "cli:codex/send": Object.freeze({ module: route20 }), - "cli:groups/add": Object.freeze({ + "cli:codex/status": Object.freeze({ module: route21 }), - "cli:groups/create": Object.freeze({ + "cli:codex/wait": Object.freeze({ module: route22 }), - "cli:groups/delete": Object.freeze({ + "cli:codex/watch": Object.freeze({ module: route23 }), - "cli:groups/get": Object.freeze({ + "cli:doctor": Object.freeze({ module: route24 }), - "cli:groups/list": Object.freeze({ + "cli:groups/add": Object.freeze({ module: route25 }), - "cli:groups/members": Object.freeze({ + "cli:groups/create": Object.freeze({ module: route26 }), - "cli:groups/remove": Object.freeze({ + "cli:groups/delete": Object.freeze({ module: route27 }), - "cli:groups/set": Object.freeze({ + "cli:groups/get": Object.freeze({ module: route28 }), - "cli:groups/update": Object.freeze({ + "cli:groups/list": Object.freeze({ module: route29 }), - "cli:history": Object.freeze({ + "cli:groups/members": Object.freeze({ module: route30 }), - "cli:send": Object.freeze({ + "cli:groups/remove": Object.freeze({ module: route31 }), - "cli:skills/add": Object.freeze({ + "cli:groups/set": Object.freeze({ module: route32 }), - "cli:skills/list": Object.freeze({ + "cli:groups/update": Object.freeze({ module: route33 }), - "cli:skills/remove": Object.freeze({ + "cli:history": Object.freeze({ module: route34 }), - "cli:thread": Object.freeze({ + "cli:send": Object.freeze({ module: route35 + }), + "cli:skills/add": Object.freeze({ + module: route36 + }), + "cli:skills/list": Object.freeze({ + module: route37 + }), + "cli:skills/remove": Object.freeze({ + module: route38 + }), + "cli:thread": Object.freeze({ + module: route39 }) }); const commands = Object.freeze([ @@ -37494,6 +38823,131 @@ var __webpack_modules__ = { "rendered": true, "routeId": "cli:bots/update" }, + { + "aliases": [], + "description": "Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).", + "exitCode": "result", + "options": [ + { + "defaultValue": 100, + "key": "limit", + "kind": "number", + "option": "limit", + "repeated": false, + "required": false + }, + { + "key": "port", + "kind": "number", + "option": "port", + "repeated": false, + "required": false + }, + { + "key": "threadId", + "kind": "string", + "option": "thread-id", + "positional": 0, + "repeated": false, + "required": true + } + ], + "path": [ + "chatgpt-desktop", + "read" + ], + "rendered": true, + "routeId": "cli:chatgpt-desktop/read" + }, + { + "aliases": [], + "description": "EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.", + "exitCode": "result", + "options": [ + { + "key": "port", + "kind": "number", + "option": "port", + "repeated": false, + "required": false + }, + { + "key": "text", + "kind": "string", + "option": "text", + "positional": 0, + "repeated": true, + "required": true + }, + { + "key": "threadId", + "kind": "string", + "option": "thread-id", + "repeated": false, + "required": false + } + ], + "path": [ + "chatgpt-desktop", + "send" + ], + "render": { + "maxElapsedMs": 120000 + }, + "rendered": true, + "routeId": "cli:chatgpt-desktop/send" + }, + { + "aliases": [], + "description": "Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.", + "exitCode": "result", + "options": [ + { + "description": "Local CDP port (default 9222)", + "key": "port", + "kind": "number", + "option": "port", + "repeated": false, + "required": false + } + ], + "path": [ + "chatgpt-desktop", + "status" + ], + "rendered": true, + "routeId": "cli:chatgpt-desktop/status" + }, + { + "aliases": [], + "description": "List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).", + "exitCode": "result", + "options": [ + { + "defaultValue": 50, + "description": "Max threads (1-200)", + "key": "limit", + "kind": "number", + "option": "limit", + "repeated": false, + "required": false + }, + { + "description": "Local CDP port", + "key": "port", + "kind": "number", + "option": "port", + "repeated": false, + "required": false + } + ], + "path": [ + "chatgpt-desktop", + "threads" + ], + "rendered": true, + "routeId": "cli:chatgpt-desktop/threads" + }, { "aliases": [], "description": "Send to an explicitly enabled live Claude Code channel and wait for its reply.", @@ -39076,27 +40530,27 @@ var __webpack_modules__ = { instanceId: processLifetime.instanceId, pid: processLifetime.pid }; - const result = await (0, _agent_bundle_runtime__rspack_import_41.iC)({ + const result = await (0, _agent_bundle_runtime__rspack_import_45.iC)({ capabilities: { - command: (0, _agent_bundle_runtime__rspack_import_41.hU)(), - filesystem: (0, _agent_bundle_runtime__rspack_import_41.hU)(), - network: (0, _agent_bundle_runtime__rspack_import_41.hU)(), - projectRoot: (0, _agent_bundle_runtime__rspack_import_41.qC)({ + command: (0, _agent_bundle_runtime__rspack_import_45.hU)(), + filesystem: (0, _agent_bundle_runtime__rspack_import_45.hU)(), + network: (0, _agent_bundle_runtime__rspack_import_45.hU)(), + projectRoot: (0, _agent_bundle_runtime__rspack_import_45.qC)({ root: cwd }, 'derived') }, - host: (0, _agent_bundle_runtime__rspack_import_41.hU)('unsupported-surface'), + host: (0, _agent_bundle_runtime__rspack_import_45.hU)('unsupported-surface'), invocation: { kind: 'cli', operationId: command.routeId, surface: command.path.join(' ') }, - lineage: (0, _agent_bundle_runtime__rspack_import_41.hU)('unsupported-surface'), + lineage: (0, _agent_bundle_runtime__rspack_import_45.hU)('unsupported-surface'), plugin: pluginRoot.identity, process: processHit, signal: context.signal, - terminal: (0, _agent_bundle_runtime__rspack_import_41.qC)(context.terminal, 'native'), - workspace: (0, _agent_bundle_runtime__rspack_import_41.qC)({ + terminal: (0, _agent_bundle_runtime__rspack_import_45.qC)(context.terminal, 'native'), + workspace: (0, _agent_bundle_runtime__rspack_import_45.qC)({ root: cwd }, 'derived') }, async ()=>route.module.default({ @@ -39203,7 +40657,7 @@ var __webpack_modules__ = { return stream; } }); - const dispatcher = (0, _agent_bundle_runtime__rspack_import_42.jK)(host); + const dispatcher = (0, _agent_bundle_runtime__rspack_import_46.jK)(host); return Object.freeze({ close: async ()=>{ await worker.terminate(); diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index f444adf..cb43c34 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8084,6 +8084,1108 @@ var __webpack_modules__ = { module.exports = __webpack_require__("./node_modules/react/cjs/react.react-server.development.js"); } }, + "./src/core/chatgpt-desktop/app-server-fallback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); + async function appServerListThreads({ limit = 50 } = {}) { + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit + }); + return { + backend: 'app-server', + limit: out.limit, + threads: out.threads.map((thread)=>({ + threadId: String(thread.id ?? ''), + title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), + pinned: false, + selected: false, + kind: 'codex' + })) + }; + } + async function appServerReadThread({ threadId, limit = 100 }) { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + let turns = []; + try { + const read = await client.request('thread/read', { + threadId + }); + const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; + turns = normalizeTurns(raw).slice(-limit); + } catch { + const items = await client.request('thread/items/list', { + threadId, + limit: Math.min(limit, 100) + }); + turns = normalizeTurns(items.data ?? []).slice(-limit); + } + return { + threadId, + turns, + backend: 'app-server', + limit + }; + } finally{ + client.close(); + } + } + async function appServerSendMessage({ threadId, text }) { + if (!threadId) { + return { + threadId: 'new', + backend: 'app-server', + experimental: false, + delivery: 'rejected', + message: 'app-server fallback requires an existing threadId; starting a new Desktop thread needs CDP' + }; + } + const receipt = await (0, _codex_bridge_js__rspack_import_0.ZS)(threadId, text); + return { + threadId, + backend: 'app-server', + experimental: false, + delivery: receipt.delivery ?? 'accepted', + message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined + }; + } + async function appServerWaitForReply({ threadId, timeoutMs = 60000 }) { + const baseline = await appServerReadThread({ + threadId, + limit: 200 + }); + const seen = new Set(baseline.turns.map((turn)=>turn.turnKey)); + const deadline = Date.now() + timeoutMs; + while(Date.now() < deadline){ + await new Promise((resolve)=>setTimeout(resolve, 400)); + const page = await appServerReadThread({ + threadId, + limit: 200 + }); + const fresh = page.turns.filter((turn)=>!seen.has(turn.turnKey) && turn.role === 'assistant' && turn.text); + const reply = fresh.at(-1)?.text ?? ''; + if (reply) { + return { + threadId, + reply, + backend: 'app-server', + experimental: false, + delivery: 'replied' + }; + } + } + return { + threadId, + reply: '', + backend: 'app-server', + experimental: false, + delivery: 'timeout' + }; + } + async function appServerOpenThread(threadId) { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + await client.request('thread/resume', { + threadId, + excludeTurns: true + }); + return { + threadId, + backend: 'app-server' + }; + } finally{ + client.close(); + } + } + async function appServerStatusProbe() { + const status = await (0, _codex_bridge_js__rspack_import_0.MU)(); + return { + reachable: Boolean(status.reachable && status.mode === 'daemon'), + mode: typeof status.mode === 'string' ? status.mode : undefined, + socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined + }; + } + function normalizeTurns(raw) { + const turns = []; + for (const [index, item] of raw.entries()){ + if (!item || typeof item !== 'object') continue; + const row = item; + const text = typeof row.text === 'string' ? row.text : typeof row.content === 'string' ? row.content : ''; + const type = String(row.type ?? row.role ?? ''); + let role = 'assistant'; + if (/user/i.test(type)) role = 'user'; + else if (/status|system|reasoning/i.test(type) && !text) role = 'status'; + turns.push({ + turnKey: String(row.id ?? row.turnId ?? index), + role, + text + }); + } + return turns; + } + __webpack_require__.d(__webpack_exports__, { + Ab: ()=>appServerSendMessage, + Jf: ()=>appServerReadThread, + OI: ()=>appServerListThreads, + bk: ()=>appServerWaitForReply, + dM: ()=>appServerStatusProbe, + zu: ()=>appServerOpenThread + }); + }, + "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _cdp_session_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); + var _cdp_dom_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); + var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + class CdpChatGptDesktopAdapter { + #port = (0, _loopback_js__rspack_import_3.L0)(); + #session = null; + #version = null; + #pageSessionId = null; + #mainTargetId = null; + async connect({ port }) { + await this.close(); + this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + const session = new _cdp_session_js__rspack_import_1.a(this.#port); + try { + this.#version = await session.connect(); + this.#session = session; + await this.#attachMainWindow(); + } catch (error) { + session.close(); + this.#session = null; + throw error; + } + } + async listTargets() { + const session = this.#requireSession(); + const result = await session.send('Target.getTargets'); + return (0, _cdp_dom_js__rspack_import_2.Mr)(result.targetInfos ?? []); + } + async listThreads({ limit = 50 } = {}) { + const sessionId = await this.#ensurePageSession(); + const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + limit + }); + return { + threads, + backend: 'cdp', + limit + }; + } + async readThread({ threadId, limit = 100 }) { + const sessionId = await this.#ensurePageSession(); + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await delay(150); + const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + limit + }); + return { + threadId, + turns, + backend: 'cdp', + limit + }; + } + async sendMessage({ threadId, text }) { + const sessionId = await this.#ensurePageSession(); + if (threadId) { + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await delay(100); + } + await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + return { + threadId: threadId ?? 'new', + backend: 'cdp', + experimental: true, + delivery: 'accepted', + message: 'Submitted via experimental CDP composer path' + }; + } + async waitForReply({ threadId, timeoutMs = 60000 }) { + const sessionId = await this.#ensurePageSession(); + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + const deadline = Date.now() + timeoutMs; + let previousKeys = new Set(); + let lastAssistant = ''; + let stable = 0; + const baseline = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + limit: 500 + }); + previousKeys = new Set(baseline.map((t)=>t.turnKey)); + while(Date.now() < deadline){ + await delay(400); + const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + limit: 500 + }); + const fresh = turns.filter((t)=>!previousKeys.has(t.turnKey) && t.role === 'assistant'); + const candidate = fresh.at(-1)?.text ?? ''; + if (candidate && candidate === lastAssistant) { + stable += 1; + if (stable >= 3) { + return { + threadId, + reply: candidate, + backend: 'cdp', + experimental: true, + delivery: 'replied' + }; + } + } else if (candidate) { + lastAssistant = candidate; + stable = 0; + } + } + return { + threadId, + reply: lastAssistant, + backend: 'cdp', + experimental: true, + delivery: lastAssistant ? 'replied' : 'timeout' + }; + } + async openThread(threadId) { + const sessionId = await this.#ensurePageSession(); + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + return { + threadId, + backend: 'cdp' + }; + } + async status() { + try { + const version = this.#version ?? await _cdp_session_js__rspack_import_1.a.fetchVersion(this.#port); + let targetCount; + let mainWindowTargetId; + if (this.#session && !this.#session.closed) { + const targets = await this.listTargets(); + targetCount = targets.length; + mainWindowTargetId = (0, _cdp_dom_js__rspack_import_2.C2)(targets)?.targetId ?? null; + } else { + const list = await _cdp_session_js__rspack_import_1.a.fetchJsonList(this.#port); + targetCount = list.length; + } + return { + reachable: true, + port: this.#port, + host: '127.0.0.1', + browser: typeof version.Browser === 'string' ? version.Browser : undefined, + protocolVersion: typeof version['Protocol-Version'] === 'string' ? version['Protocol-Version'] : undefined, + webSocketDebuggerUrl: typeof version.webSocketDebuggerUrl === 'string' ? version.webSocketDebuggerUrl : undefined, + targetCount, + mainWindowTargetId: mainWindowTargetId ?? this.#mainTargetId, + message: 'ChatGPT Desktop CDP endpoint reachable on 127.0.0.1', + exitCode: 0 + }; + } catch (error) { + return { + reachable: false, + port: this.#port, + host: '127.0.0.1', + message: error instanceof Error ? error.message : 'ChatGPT Desktop CDP endpoint unreachable on 127.0.0.1', + exitCode: 1 + }; + } + } + async close() { + this.#pageSessionId = null; + this.#mainTargetId = null; + this.#version = null; + this.#session?.close(); + this.#session = null; + } + async #attachMainWindow() { + const targets = await this.listTargets(); + const main = (0, _cdp_dom_js__rspack_import_2.C2)(targets); + if (!main) { + throw new _errors_js__rspack_import_0.sO(`No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`); + } + const attached = await this.#requireSession().send('Target.attachToTarget', { + targetId: main.targetId, + flatten: true + }); + this.#mainTargetId = main.targetId; + this.#pageSessionId = attached.sessionId; + } + async #ensurePageSession() { + this.#requireSession(); + if (!this.#pageSessionId) await this.#attachMainWindow(); + if (!this.#pageSessionId) { + throw new _errors_js__rspack_import_0.sO('Failed to attach to ChatGPT Desktop main window'); + } + return this.#pageSessionId; + } + #requireSession() { + if (!this.#session || this.#session.closed) { + throw new _errors_js__rspack_import_0.sO('Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.'); + } + return this.#session; + } + } + function delay(ms) { + return new Promise((resolve)=>setTimeout(resolve, ms)); + } + __webpack_require__.d(__webpack_exports__, { + a: ()=>CdpChatGptDesktopAdapter + }); + }, + "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + const MAIN_WINDOW_URL = 'app://-/index.html'; + const ATTR = { + threadRow: 'data-app-action-sidebar-thread-row', + threadId: 'data-app-action-sidebar-thread-id', + threadTitle: 'data-app-action-sidebar-thread-title', + threadPinned: 'data-app-action-sidebar-thread-pinned', + threadSelected: 'data-app-action-sidebar-thread-selected', + threadKind: 'data-app-action-sidebar-thread-kind', + turnKey: 'data-turn-key', + userBubble: 'data-user-message-bubble', + timelineScroll: 'data-app-action-timeline-scroll', + virtualizedTurn: 'data-virtualized-turn-content' + }; + const SELECTORS = { + threadRow: `[role="button"][${ATTR.threadRow}]`, + turn: `[${ATTR.turnKey}]`, + userBubble: `[${ATTR.userBubble}]`, + timelineScroll: `[${ATTR.timelineScroll}]`, + mainSurface: 'main', + composerCandidates: [ + 'main [contenteditable="true"]', + 'main textarea', + '[data-app-action-composer] [contenteditable="true"]', + '[data-app-action-composer] textarea', + 'form [contenteditable="true"]', + 'form textarea' + ], + sendButtonCandidates: [ + 'button[data-app-action-send]', + 'button[aria-label="Send"]', + 'button[aria-label="Send message"]', + 'main button[type="submit"]' + ] + }; + function isMainWindowTarget(target) { + return target.type === 'page' && target.url === MAIN_WINDOW_URL; + } + function summarizeTargetInfos(targetInfos) { + return targetInfos.filter((t)=>typeof t.targetId === 'string' && typeof t.type === 'string').map((t)=>({ + targetId: String(t.targetId), + type: String(t.type), + title: typeof t.title === 'string' ? t.title : '', + url: typeof t.url === 'string' ? t.url : '', + attached: Boolean(t.attached) + })); + } + function pickMainWindowTarget(targets) { + return targets.find((t)=>isMainWindowTarget(t)) ?? null; + } + const LIST_THREADS_EXPRESSION = `(() => { + const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); + return rows.map((row) => ({ + threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || '', + title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), + pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', + selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', + kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + })).filter((t) => t.threadId); +})()`; + function openThreadExpression(threadId) { + return `(() => { + const id = ${JSON.stringify(threadId)}; + const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); + const row = rows.find((el) => el.getAttribute(${JSON.stringify(ATTR.threadId)}) === id); + if (!row) return { ok: false, error: 'thread-not-found' }; + row.click(); + return { ok: true, threadId: id }; + })()`; + } + const READ_THREAD_EXPRESSION = `(() => { + const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + const mains = Array.from(document.querySelectorAll('main')); + const surface = mains.length >= 2 ? mains[1] : (mains[0] || document.body); + const root = scroll || surface; + const collected = new Map(); + const statusRe = /^Worked for \\d+s$/i; + const harvest = () => { + for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { + const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; + if (!turnKey || collected.has(turnKey)) continue; + const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); + const text = (el.innerText || '').trim(); + let role = 'assistant'; + if (user) role = 'user'; + else if (!text || statusRe.test(text)) role = 'status'; + collected.set(turnKey, { turnKey, role, text }); + } + }; + const maxPasses = 80; + let stable = 0; + let lastSize = -1; + if (scroll) scroll.scrollTop = 0; + for (let i = 0; i < maxPasses; i++) { + harvest(); + if (collected.size === lastSize) { + stable += 1; + if (stable >= 3) break; + } else { + stable = 0; + lastSize = collected.size; + } + if (scroll) { + const next = Math.min(scroll.scrollHeight, scroll.scrollTop + Math.max(scroll.clientHeight, 200)); + if (next <= scroll.scrollTop && stable >= 1) break; + scroll.scrollTop = next; + } else { + break; + } + } + harvest(); + return Array.from(collected.values()); +})()`; + function sendMessageExpression(text) { + const composers = JSON.stringify([ + ...SELECTORS.composerCandidates + ]); + const buttons = JSON.stringify([ + ...SELECTORS.sendButtonCandidates + ]); + return `(() => { + const text = ${JSON.stringify(text)}; + const composers = ${composers}; + let composer = null; + for (const sel of composers) { + composer = document.querySelector(sel); + if (composer) break; + } + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.focus(); + if (composer.isContentEditable) { + composer.textContent = text; + composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: text, inputType: 'insertText' })); + } else if ('value' in composer) { + composer.value = text; + composer.dispatchEvent(new Event('input', { bubbles: true })); + } else { + return { ok: false, error: 'composer-unsupported' }; + } + const buttons = ${buttons}; + let sent = false; + for (const sel of buttons) { + const btn = document.querySelector(sel); + if (btn && !btn.disabled) { btn.click(); sent = true; break; } + } + if (!sent) { + composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true })); + composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', bubbles: true })); + } + return { ok: true, sentVia: sent ? 'button' : 'enter' }; + })()`; + } + async function listThreadsFromDom(session, sessionId, { limit = 50 } = {}) { + const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { + sessionId + }); + if (!Array.isArray(rows)) return []; + return rows.slice(0, limit).map((row)=>({ + threadId: String(row.threadId), + title: String(row.title ?? ''), + pinned: Boolean(row.pinned), + selected: Boolean(row.selected), + kind: String(row.kind ?? 'unknown') + })); + } + async function openThreadInDom(session, sessionId, threadId) { + const result = await session.evaluate(openThreadExpression(threadId), { + sessionId + }); + if (!result?.ok) { + throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); + } + } + async function readTurnsFromDom(session, sessionId, { limit = 100 } = {}) { + const turns = await session.evaluate(READ_THREAD_EXPRESSION, { + sessionId + }); + if (!Array.isArray(turns)) return []; + return turns.slice(-limit).map((turn)=>({ + turnKey: String(turn.turnKey), + role: turn.role === 'user' || turn.role === 'status' ? turn.role : 'assistant', + text: String(turn.text ?? '') + })); + } + async function sendMessageInDom(session, sessionId, text) { + try { + await session.send('Input.insertText', { + text + }, { + sessionId + }); + } catch {} + const result = await session.evaluate(sendMessageExpression(text), { + sessionId + }); + if (!result?.ok) { + throw new Error(result?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${result?.error ?? 'unknown'}`); + } + return { + sentVia: result.sentVia ?? 'unknown' + }; + } + __webpack_require__.d(__webpack_exports__, { + AY: ()=>listThreadsFromDom, + C2: ()=>pickMainWindowTarget, + JU: ()=>readTurnsFromDom, + Kl: ()=>openThreadInDom, + Mr: ()=>summarizeTargetInfos, + lh: ()=>sendMessageInDom + }); + }, + "./src/core/chatgpt-desktop/cdp-session.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _loopback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + class CdpSession { + #port; + #ws = null; + #nextId = 1; + #pending = new Map(); + #closed = false; + constructor(port){ + this.#port = port; + } + get port() { + return this.#port; + } + get closed() { + return this.#closed || this.#ws === null || this.#ws.readyState === WebSocket.CLOSED; + } + static async fetchVersion(port, { signal } = {}) { + const base = (0, _loopback_js__rspack_import_1.NJ)(port); + let response; + try { + response = await fetch(`${base}/json/version`, { + signal + }); + } catch (error) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/version: ` + (error instanceof Error ? error.message : String(error))); + } + if (!response.ok) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP /json/version returned HTTP ${response.status}`); + } + return await response.json(); + } + static async fetchJsonList(port, { signal } = {}) { + const base = (0, _loopback_js__rspack_import_1.NJ)(port); + let response; + try { + response = await fetch(`${base}/json/list`, { + signal + }); + } catch (error) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/list: ` + (error instanceof Error ? error.message : String(error))); + } + if (!response.ok) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP /json/list returned HTTP ${response.status}`); + } + const body = await response.json(); + return Array.isArray(body) ? body : []; + } + async connect({ signal } = {}) { + if (this.#ws && !this.closed) { + throw new Error('CDP session already connected'); + } + const version = await CdpSession.fetchVersion(this.#port, { + signal + }); + const rawUrl = version.webSocketDebuggerUrl; + if (typeof rawUrl !== 'string' || !rawUrl) { + throw new _errors_js__rspack_import_0.sO('CDP /json/version omitted webSocketDebuggerUrl'); + } + const url = (0, _loopback_js__rspack_import_1.jv)(rawUrl); + const parsed = new URL(url); + (0, _loopback_js__rspack_import_1.tb)(parsed.hostname); + await new Promise((resolve, reject)=>{ + const ws = new WebSocket(url); + this.#ws = ws; + const onAbort = ()=>{ + ws.close(); + reject(new Error('CDP connect aborted')); + }; + signal?.addEventListener('abort', onAbort, { + once: true + }); + ws.addEventListener('open', ()=>{ + signal?.removeEventListener('abort', onAbort); + resolve(); + }, { + once: true + }); + ws.addEventListener('error', ()=>{ + signal?.removeEventListener('abort', onAbort); + reject(new _errors_js__rspack_import_0.sO(`CDP WebSocket failed for ${url}`)); + }, { + once: true + }); + ws.addEventListener('message', (event)=>this.#onMessage(event.data)); + ws.addEventListener('close', ()=>{ + this.#closed = true; + for (const [, pending] of this.#pending){ + pending.reject(new Error('CDP WebSocket closed')); + } + this.#pending.clear(); + }); + }); + this.#closed = false; + return version; + } + async send(method, params, { sessionId } = {}) { + if (!this.#ws || this.#ws.readyState !== WebSocket.OPEN) { + throw new _errors_js__rspack_import_0.sO('CDP session is not connected'); + } + const id = this.#nextId++; + const payload = { + id, + method + }; + if (params !== undefined) payload.params = params; + if (sessionId !== undefined) payload.sessionId = sessionId; + return await new Promise((resolve, reject)=>{ + this.#pending.set(id, { + resolve: (value)=>resolve(value), + reject + }); + this.#ws.send(JSON.stringify(payload)); + }); + } + async evaluate(expression, { sessionId, awaitPromise = true } = {}) { + const result = await this.send('Runtime.evaluate', { + expression, + returnByValue: true, + awaitPromise + }, { + sessionId + }); + if (result.exceptionDetails) { + const text = result.exceptionDetails.exception?.description || result.exceptionDetails.text || 'Runtime.evaluate failed'; + throw new Error(text); + } + return result.result?.value; + } + close() { + this.#closed = true; + this.#ws?.close(); + this.#ws = null; + } + #onMessage(data) { + let message; + try { + message = JSON.parse(String(data)); + } catch { + return; + } + if (typeof message.id !== 'number') return; + const pending = this.#pending.get(message.id); + if (!pending) return; + this.#pending.delete(message.id); + if (message.error) { + pending.reject(new Error(message.error.message || 'CDP error')); + return; + } + pending.resolve(message.result); + } + } + __webpack_require__.d(__webpack_exports__, { + a: ()=>CdpSession + }); + }, + "./src/core/chatgpt-desktop/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + class NotImplementedError extends Error { + code = 'NOT_IMPLEMENTED'; + delivery = 'rejected'; + reason = 'not-implemented'; + constructor(operation, detail){ + super(detail ? `ChatGPT Desktop ${operation} is not implemented: ${detail}` : `ChatGPT Desktop ${operation} is not implemented`); + this.name = 'NotImplementedError'; + } + } + class CdpHostRejectedError extends Error { + code = 'CDP_HOST_REJECTED'; + delivery = 'rejected'; + reason = 'cdp-host-rejected'; + constructor(host){ + super(`ChatGPT Desktop CDP rejects non-loopback host ${JSON.stringify(host)}. ` + 'Connect to 127.0.0.1 only; there is no remote transport.'); + this.name = 'CdpHostRejectedError'; + } + } + class CdpUnreachableError extends Error { + code = 'CDP_UNREACHABLE'; + delivery = 'rejected'; + reason = 'cdp-unreachable'; + constructor(message){ + super(message); + this.name = 'CdpUnreachableError'; + } + } + __webpack_require__.d(__webpack_exports__, { + EH: ()=>NotImplementedError, + c$: ()=>CdpHostRejectedError, + sO: ()=>CdpUnreachableError + }); + }, + "./src/core/chatgpt-desktop/facade.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _cdp_adapter_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-adapter.ts"); + var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); + var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + class ChatGptDesktopFacade { + #cdp; + #port; + #cdpConnected = false; + constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)()){ + this.#cdp = cdp; + this.#port = port; + } + async connect({ port }) { + this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + try { + await this.#cdp.connect({ + port: this.#port + }); + this.#cdpConnected = true; + } catch (error) { + this.#cdpConnected = false; + throw error; + } + } + async listTargets() { + await this.#ensureCdp(); + return this.#cdp.listTargets(); + } + async listThreads(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.listThreads(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.OI)(options); + } + } + async readThread(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.readThread(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.Jf)(options); + } + } + async sendMessage(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.sendMessage(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.Ab)(options); + } + } + async waitForReply(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.waitForReply(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.bk)(options); + } + } + async openThread(threadId) { + try { + await this.#ensureCdp(); + return await this.#cdp.openThread(threadId); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.zu)(threadId); + } + } + async status() { + const cdpStatus = await this.#cdp.status(); + let appServerFallback; + try { + appServerFallback = await (0, _app_server_fallback_js__rspack_import_1.dM)(); + } catch { + appServerFallback = { + reachable: false + }; + } + const reachable = cdpStatus.reachable || Boolean(appServerFallback?.reachable); + return { + ...cdpStatus, + port: this.#port, + appServerFallback, + reachable, + message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server fallback is available' : cdpStatus.message, + exitCode: reachable ? 0 : 1 + }; + } + async close() { + this.#cdpConnected = false; + await this.#cdp.close(); + } + async #ensureCdp() { + if (this.#cdpConnected) return; + await this.#cdp.connect({ + port: this.#port + }); + this.#cdpConnected = true; + } + } + function isCdpFailure(error) { + if (error instanceof _errors_js__rspack_import_2.sO) return true; + if (error instanceof _errors_js__rspack_import_2.EH) return false; + if (error && typeof error === 'object' && 'code' in error) { + const code = String(error.code); + return code === 'CDP_UNREACHABLE' || code === 'CDP_HOST_REJECTED'; + } + return false; + } + let activeAdapter = null; + function getChatGptDesktopAdapter() { + if (!activeAdapter) activeAdapter = new ChatGptDesktopFacade(); + return activeAdapter; + } + function setChatGptDesktopAdapterForTests(adapter) { + activeAdapter = adapter; + } + __webpack_require__.d(__webpack_exports__, { + PP: ()=>getChatGptDesktopAdapter + }); + }, + "./src/core/chatgpt-desktop/loopback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + const LOOPBACK = new Set([ + '127.0.0.1', + 'localhost', + '::1' + ]); + const DEFAULT_CDP_PORT = 9222; + const CDP_LOOPBACK_HOST = '127.0.0.1'; + function isLoopbackHostname(hostname) { + const host = String(hostname || '').toLowerCase().replace(/^\[|\]$/g, ''); + return LOOPBACK.has(host); + } + function assertLoopbackHostname(hostname) { + if (!isLoopbackHostname(hostname)) { + throw new _errors_js__rspack_import_0.c$(hostname); + } + } + function cdpHttpBase(port) { + if (!Number.isInteger(port) || port < 1 || port > 65535) { + throw new RangeError('CDP port must be an integer 1-65535'); + } + return `http://${CDP_LOOPBACK_HOST}:${port}`; + } + function forceLoopbackWebSocketUrl(raw) { + let url; + try { + url = new URL(raw); + } catch { + throw new _errors_js__rspack_import_0.c$(String(raw)); + } + assertLoopbackHostname(url.hostname); + if (url.protocol !== 'ws:' && url.protocol !== 'wss:') { + throw new Error(`Expected ws(s) debugger URL, got ${url.protocol}`); + } + url.hostname = CDP_LOOPBACK_HOST; + url.protocol = 'ws:'; + return url.toString(); + } + function resolveCdpPort(env = process.env, explicit) { + if (explicit !== undefined) { + if (!Number.isInteger(explicit) || explicit < 1 || explicit > 65535) { + throw new RangeError('CDP port must be an integer 1-65535'); + } + return explicit; + } + const raw = (env.CHATGPT_DESKTOP_CDP_PORT || '').trim(); + if (!raw) return DEFAULT_CDP_PORT; + const port = Number.parseInt(raw, 10); + if (!Number.isInteger(port) || port < 1 || port > 65535) { + throw new RangeError('CHATGPT_DESKTOP_CDP_PORT must be an integer 1-65535'); + } + return port; + } + __webpack_require__.d(__webpack_exports__, { + L0: ()=>resolveCdpPort, + NJ: ()=>cdpHttpBase, + jv: ()=>forceLoopbackWebSocketUrl, + tb: ()=>assertLoopbackHostname + }); + }, + "./src/core/chatgpt-desktop/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var zod__rspack_import_4 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _codex_contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); + var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _facade_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/facade.ts"); + var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + const threadId = zod__rspack_import_4.YjP().min(1).max(256); + const statusSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional() + }).strict(); + const listThreadsSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + }).strict(); + const readThreadSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId, + limit: zod__rspack_import_4.aig().int().min(1).max(500).default(100) + }).strict(); + const sendSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId: threadId.optional(), + text: zod__rspack_import_4.YjP().min(1).max(100000) + }).strict(); + const waitReplySchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId, + timeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(60000) + }).strict(); + const resultSchema = zod__rspack_import_4.Ikc({ + exitCode: zod__rspack_import_4.KCZ([ + zod__rspack_import_4.euz(0), + zod__rspack_import_4.euz(1) + ]) + }).catchall(zod__rspack_import_4.Pq9()); + async function withAdapter(port, run) { + const adapter = (0, _facade_js__rspack_import_2.PP)(); + const resolved = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + try { + await adapter.connect({ + port: resolved + }); + } catch {} + return run(adapter); + } + function asResult(value) { + return resultSchema.parse(value); + } + function mapError(error) { + if (error instanceof _errors_js__rspack_import_1.EH) { + return asResult({ + delivery: 'rejected', + reason: 'not-implemented', + code: 'NOT_IMPLEMENTED', + error: error.message, + exitCode: 1 + }); + } + const base = (0, _codex_contract_js__rspack_import_0.DG)(error); + if (error && typeof error === 'object' && 'code' in error) { + return asResult({ + ...base, + code: String(error.code) + }); + } + return asResult(base); + } + async function statusOperation(input) { + try { + const status = await withAdapter(input.port, (adapter)=>adapter.status()); + return asResult(status); + } catch (error) { + return mapError(error); + } + } + async function listThreadsOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ + limit: input.limit + })); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } + async function readThreadOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ + threadId: input.threadId, + limit: input.limit + })); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } + async function sendOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.sendMessage({ + threadId: input.threadId, + text: input.text + })); + return asResult({ + ...out, + exitCode: out.delivery === 'accepted' ? 0 : 1 + }); + } catch (error) { + return mapError(error); + } + } + async function waitReplyOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.waitForReply({ + threadId: input.threadId, + timeoutMs: input.timeoutMs + })); + return asResult({ + ...out, + exitCode: out.delivery === 'replied' ? 0 : 1 + }); + } catch (error) { + return mapError(error); + } + } + function resultText(result) { + if (result.error) return String(result.error); + if (result.reachable === true) { + const backend = result.appServerFallback && typeof result.appServerFallback === 'object' ? ` cdp + app-server probe` : ''; + return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; + } + if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); + if (Array.isArray(result.threads)) { + return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; + } + if (Array.isArray(result.turns)) { + return `${result.turns.length} turns on ${result.threadId} via ${result.backend ?? 'unknown'}`; + } + if (result.delivery === 'accepted') { + return `Sent on ${result.threadId} via ${result.backend}${result.experimental ? ' (experimental)' : ''}`; + } + if (result.delivery === 'replied') { + return String(result.reply ?? 'replied'); + } + if (result.delivery) return `delivery ${result.delivery}`; + return JSON.stringify(result); + } + __webpack_require__.d(__webpack_exports__, { + D6: ()=>resultText, + UK: ()=>readThreadOperation, + UP: ()=>sendOperation, + Uj: ()=>statusOperation, + Zg: ()=>waitReplyOperation, + tJ: ()=>listThreadsOperation + }, { + FC: listThreadsSchema, + FD: resultSchema, + Fn: waitReplySchema, + Wi: sendSchema, + aW: statusSchema, + so: readThreadSchema + }); + }, "./src/core/claude-routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_1 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _claude_channel_js__rspack_import_0 = __webpack_require__("./src/core/claude-channel.js"); @@ -8570,80 +9672,311 @@ var __webpack_modules__ = { kind: record.isGroup ? 'group' : 'bot', name: record.name }); - const entrySchema = zod__rspack_import_3.Ikc({ - id: zod__rspack_import_3.YjP(), - kind: zod__rspack_import_3.YjP(), - role: zod__rspack_import_3.YjP().optional(), - text: zod__rspack_import_3.YjP(), - truncated: zod__rspack_import_3.zMY(), - fullLength: zod__rspack_import_3.aig().int().min(0), - timestampMs: zod__rspack_import_3.aig().optional() + const entrySchema = zod__rspack_import_3.Ikc({ + id: zod__rspack_import_3.YjP(), + kind: zod__rspack_import_3.YjP(), + role: zod__rspack_import_3.YjP().optional(), + text: zod__rspack_import_3.YjP(), + truncated: zod__rspack_import_3.zMY(), + fullLength: zod__rspack_import_3.aig().int().min(0), + timestampMs: zod__rspack_import_3.aig().optional() + }); + const ENTRY_FULL_MAX = 20000; + const TRANSCRIPT_TOTAL_MAX = 200000; + const ENTRY_META_MAX = 200; + const RECEIPT_CURSOR_MAX = 1024; + const entryFields = zod__rspack_import_3.Ikc({ + id: zod__rspack_import_3.YjP().default(''), + kind: zod__rspack_import_3.YjP().default('message'), + role: zod__rspack_import_3.YjP().optional(), + timestampMs: zod__rspack_import_3.aig().optional() + }); + const capMeta = (value)=>value.length > ENTRY_META_MAX ? `${value.slice(0, ENTRY_META_MAX)}…` : value; + const threadEntry = (raw)=>{ + const fields = entryFields.safeParse(raw); + const full = (0, _core_transcript_js__rspack_import_2.u0)(raw); + const truncated = full.length > ENTRY_FULL_MAX; + const text = truncated ? full.slice(0, ENTRY_FULL_MAX) : full; + if (!fields.success) { + return { + id: '', + kind: 'unknown', + text, + truncated, + fullLength: full.length + }; + } + const { id, kind, role, timestampMs } = fields.data; + return { + id: capMeta(id), + kind: capMeta(kind), + ...role === undefined ? {} : { + role: capMeta(role) + }, + text, + truncated, + fullLength: full.length, + ...timestampMs === undefined ? {} : { + timestampMs + } + }; + }; + const metaLength = (entry)=>entry.id.length + entry.kind.length + (entry.role?.length ?? 0); + const transcriptEntries = (transcript)=>{ + const rows = (0, _core_transcript_js__rspack_import_2.xw)(transcript); + let remaining = TRANSCRIPT_TOTAL_MAX; + return rows.map((raw)=>{ + const entry = threadEntry(raw); + const allowText = Math.max(0, Math.min(entry.text.length, remaining - metaLength(entry))); + if (allowText < entry.text.length) { + entry.text = allowText <= 0 ? '' : entry.text.slice(0, allowText); + entry.truncated = entry.fullLength > entry.text.length; + } + remaining = Math.max(0, remaining - metaLength(entry) - entry.text.length); + return entry; + }); + }; + __webpack_require__.d(__webpack_exports__, { + LV: ()=>_core_gateway_js__rspack_import_0.LV, + N3: ()=>_core_transcript_js__rspack_import_2.N3, + Vq: ()=>_core_gateway_js__rspack_import_0.Vq, + bA: ()=>_core_gateway_js__rspack_import_0.bA + }, { + Oo: entrySchema, + rW: summarizeTarget, + xw: transcriptEntries, + yF: withRedactedErrors + }); + }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop list threads', + description: 'List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend "cdp" or "app-server".', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FC, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number' + }, + limit: { + type: 'number', + description: 'Maximum threads (1-200).' + } + }, + required: [] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.tJ)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.FC + }, { + "default": __rspack_default_export + }); + }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop read thread', + description: 'Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.so, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number' + }, + threadId: { + type: 'string' + }, + limit: { + type: 'number' + } + }, + required: [ + 'threadId' + ] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.UK)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.so + }, { + "default": __rspack_default_export + }); + }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop send', + description: 'EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.', + annotations: { + readOnlyHint: false + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.Wi, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + render: { + maxElapsedMs: 120000 + }, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number' + }, + threadId: { + type: 'string', + description: 'Sidebar thread id; omit to start/use a new chat.' + }, + text: { + type: 'string' + } + }, + required: [ + 'text' + ] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.UP)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.Wi + }, { + "default": __rspack_default_export + }); + }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop status', + description: 'Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.aW, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number', + description: 'Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).' + } + }, + required: [] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.Uj)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); }); - const ENTRY_FULL_MAX = 20000; - const TRANSCRIPT_TOTAL_MAX = 200000; - const ENTRY_META_MAX = 200; - const RECEIPT_CURSOR_MAX = 1024; - const entryFields = zod__rspack_import_3.Ikc({ - id: zod__rspack_import_3.YjP().default(''), - kind: zod__rspack_import_3.YjP().default('message'), - role: zod__rspack_import_3.YjP().optional(), - timestampMs: zod__rspack_import_3.aig().optional() + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.aW + }, { + "default": __rspack_default_export }); - const capMeta = (value)=>value.length > ENTRY_META_MAX ? `${value.slice(0, ENTRY_META_MAX)}…` : value; - const threadEntry = (raw)=>{ - const fields = entryFields.safeParse(raw); - const full = (0, _core_transcript_js__rspack_import_2.u0)(raw); - const truncated = full.length > ENTRY_FULL_MAX; - const text = truncated ? full.slice(0, ENTRY_FULL_MAX) : full; - if (!fields.success) { - return { - id: '', - kind: 'unknown', - text, - truncated, - fullLength: full.length - }; - } - const { id, kind, role, timestampMs } = fields.data; - return { - id: capMeta(id), - kind: capMeta(kind), - ...role === undefined ? {} : { - role: capMeta(role) + }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop wait for reply', + description: 'EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.Fn, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + render: { + maxElapsedMs: 660000 + }, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number' + }, + threadId: { + type: 'string' + }, + timeoutMs: { + type: 'number' + } }, - text, - truncated, - fullLength: full.length, - ...timestampMs === undefined ? {} : { - timestampMs - } - }; - }; - const metaLength = (entry)=>entry.id.length + entry.kind.length + (entry.role?.length ?? 0); - const transcriptEntries = (transcript)=>{ - const rows = (0, _core_transcript_js__rspack_import_2.xw)(transcript); - let remaining = TRANSCRIPT_TOTAL_MAX; - return rows.map((raw)=>{ - const entry = threadEntry(raw); - const allowText = Math.max(0, Math.min(entry.text.length, remaining - metaLength(entry))); - if (allowText < entry.text.length) { - entry.text = allowText <= 0 ? '' : entry.text.slice(0, allowText); - entry.truncated = entry.fullLength > entry.text.length; - } - remaining = Math.max(0, remaining - metaLength(entry) - entry.text.length); - return entry; + required: [ + 'threadId' + ] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.Zg)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) }); - }; + }); __webpack_require__.d(__webpack_exports__, { - LV: ()=>_core_gateway_js__rspack_import_0.LV, - N3: ()=>_core_transcript_js__rspack_import_2.N3, - Vq: ()=>_core_gateway_js__rspack_import_0.Vq, - bA: ()=>_core_gateway_js__rspack_import_0.bA + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.Fn }, { - Oo: entrySchema, - rW: summarizeTarget, - xw: transcriptEntries, - yF: withRedactedErrors + "default": __rspack_default_export }); }, "./src/mcp/grok-bot/tools/claude_send.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -21162,7 +22495,7 @@ var __webpack_modules__ = { const openSession = openCodexSession; const CODEX_VERSION_PROBE_TIMEOUT_MS = 3000; function probeLocalCodexVersion(timeoutMs = CODEX_VERSION_PROBE_TIMEOUT_MS) { - const out = spawnSync("codex", [ + const out = (0, node_child_process__rspack_import_5.spawnSync)("codex", [ "--version" ], { encoding: "utf8", @@ -21195,7 +22528,7 @@ var __webpack_modules__ = { function listDesktopProcesses(timeoutMs = DESKTOP_PROCESS_LIST_TIMEOUT_MS) { if (process.platform === "win32") return ""; try { - const out = spawnSync("ps", [ + const out = (0, node_child_process__rspack_import_5.spawnSync)("ps", [ "-eo", "args" ], { @@ -21223,7 +22556,7 @@ var __webpack_modules__ = { let desktopShimConfigured = Boolean(shim && shim.installed && shim.wrapperPointsAtShim); if (shim === undefined) { try { - const live = desktopShimStatus({ + const live = (0, _desktop_shim_js__rspack_import_8.em)({ env }); desktopShimConfigured = Boolean(live.installed && live.wrapperPointsAtShim); @@ -21250,14 +22583,14 @@ var __webpack_modules__ = { } catch (err) { if (err instanceof CodexRouteError) { const message = err.mode === "socket-absent" ? unreachableMessage(path, desktopAttached, env) : err.message; - return withStatusExitCode({ + return (0, _codex_contract_js__rspack_import_7.AQ)({ ...base, reachable: false, mode: err.mode, message }); } - if (err instanceof CodexProtocolError) return withStatusExitCode({ + if (err instanceof CodexProtocolError) return (0, _codex_contract_js__rspack_import_7.AQ)({ ...base, reachable: true, mode: err.mode, @@ -21267,7 +22600,7 @@ var __webpack_modules__ = { } session.client.close(); const daemonVersion = appServerVersion(session.init); - return withStatusExitCode({ + return (0, _codex_contract_js__rspack_import_7.AQ)({ ...base, reachable: true, mode: "daemon", @@ -21778,6 +23111,7 @@ var __webpack_modules__ = { } __webpack_require__.d(__webpack_exports__, { $3: ()=>assertThreadAllowed, + MU: ()=>codexStatus, Mr: ()=>withEnvelopeHeader, X$: ()=>listCodexThreads, ZS: ()=>sendToCodexThread, @@ -21792,7 +23126,7 @@ var __webpack_modules__ = { function statusExitCode(status) { return status.reachable && status.mode === "daemon" ? 0 : 1; } - function withStatusExitCode1(status) { + function withStatusExitCode(status) { return { ...status, exitCode: statusExitCode(status) @@ -21848,6 +23182,7 @@ var __webpack_modules__ = { }; } __webpack_require__.d(__webpack_exports__, { + AQ: ()=>withStatusExitCode, DG: ()=>outcomeFromError, Dz: ()=>outcomeFromReceipt }); @@ -22289,7 +23624,7 @@ var __webpack_modules__ = { j: ()=>openCodexConversation }); }, - "./src/core/desktop-shim.js" (__unused_rspack___webpack_module__, __unused_rspack___webpack_exports__, __webpack_require__) { + "./src/core/desktop-shim.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { var node_child_process__rspack_import_0 = __webpack_require__("node:child_process"); var node_fs__rspack_import_1 = __webpack_require__("node:fs"); var node_os__rspack_import_2 = __webpack_require__("node:os"); @@ -22306,25 +23641,25 @@ var __webpack_modules__ = { return env.CODEX_HOME || join(env.HOME || homedir(), ".codex"); } function userHomeDir(env = process.env) { - return env.HOME || homedir(); + return env.HOME || (0, node_os__rspack_import_2.homedir)(); } function defaultPaths({ env = process.env, home = userHomeDir(env) } = {}) { - const codexHome = env.CODEX_HOME || join(home, ".codex"); - const binDir = join(codexHome, "bin"); + const codexHome = env.CODEX_HOME || (0, node_path__rspack_import_3.join)(home, ".codex"); + const binDir = (0, node_path__rspack_import_3.join)(codexHome, "bin"); return { binDir, - bridgeLogPath: join(binDir, BRIDGE_LOG_FILENAME), - bridgePath: join(binDir, BRIDGE_FILENAME), + bridgeLogPath: (0, node_path__rspack_import_3.join)(binDir, BRIDGE_LOG_FILENAME), + bridgePath: (0, node_path__rspack_import_3.join)(binDir, BRIDGE_FILENAME), codexHome, - envLogPath: join(binDir, ENV_LOG_FILENAME), - envScriptPath: join(binDir, ENV_SCRIPT_FILENAME), + envLogPath: (0, node_path__rspack_import_3.join)(binDir, ENV_LOG_FILENAME), + envScriptPath: (0, node_path__rspack_import_3.join)(binDir, ENV_SCRIPT_FILENAME), label: SHIM_LABEL, - launchAgentsDir: join(home, "Library", "LaunchAgents"), - plistPath: join(home, "Library", "LaunchAgents", `${SHIM_LABEL}.plist`), - realPath: join(codexHome, STANDALONE_REAL_SUFFIX), - socketPath: join(codexHome, "app-server-control", "app-server-control.sock"), - wrapperLogPath: join(binDir, WRAPPER_LOG_FILENAME), - wrapperPath: join(binDir, WRAPPER_FILENAME) + launchAgentsDir: (0, node_path__rspack_import_3.join)(home, "Library", "LaunchAgents"), + plistPath: (0, node_path__rspack_import_3.join)(home, "Library", "LaunchAgents", `${SHIM_LABEL}.plist`), + realPath: (0, node_path__rspack_import_3.join)(codexHome, STANDALONE_REAL_SUFFIX), + socketPath: (0, node_path__rspack_import_3.join)(codexHome, "app-server-control", "app-server-control.sock"), + wrapperLogPath: (0, node_path__rspack_import_3.join)(binDir, WRAPPER_LOG_FILENAME), + wrapperPath: (0, node_path__rspack_import_3.join)(binDir, WRAPPER_FILENAME) }; } function shouldBridge(argv) { @@ -22484,7 +23819,7 @@ ts() { date -u +%Y-%m-%dT%H:%M:%SZ; } } const defaultRunner = (file, args)=>{ try { - return spawnSync(file, args, { + return (0, node_child_process__rspack_import_0.spawnSync)(file, args, { encoding: "utf8", timeout: 15000 }); @@ -22511,19 +23846,19 @@ ts() { date -u +%Y-%m-%dT%H:%M:%SZ; } } function isExecutable(path) { try { - statSync(path); + (0, node_fs__rspack_import_1.statSync)(path); } catch { return false; } try { - return (statSync(path).mode & 73) !== 0; + return ((0, node_fs__rspack_import_1.statSync)(path).mode & 73) !== 0; } catch { return false; } } function fileExists(path) { try { - statSync(path); + (0, node_fs__rspack_import_1.statSync)(path); return true; } catch { return false; @@ -22675,12 +24010,12 @@ ts() { date -u +%Y-%m-%dT%H:%M:%SZ; } } function socketStateOf(path) { try { - return statSync(path).isSocket() ? "socket" : "not-a-socket"; + return (0, node_fs__rspack_import_1.statSync)(path).isSocket() ? "socket" : "not-a-socket"; } catch (error) { return error && (error.code === "EACCES" || error.code === "EPERM") ? "permission-denied" : "absent"; } } - function desktopShimStatus1({ env = process.env, home = userHomeDir(env), platform = process.platform, runner = defaultRunner } = {}) { + function desktopShimStatus({ env = process.env, home = userHomeDir(env), platform = process.platform, runner = defaultRunner } = {}) { const paths = defaultPaths({ env, home @@ -22711,7 +24046,7 @@ ts() { date -u +%Y-%m-%dT%H:%M:%SZ; } } const desktopCliPath = platform === "darwin" ? guiCliPath : cliPath; const installed = wrapperPresent && isExecutable(paths.wrapperPath) && bridgePresent; - const socketPath = env.CODEX_APP_SERVER_SOCK || join(paths.codexHome, "app-server-control", "app-server-control.sock"); + const socketPath = env.CODEX_APP_SERVER_SOCK || (0, node_path__rspack_import_3.join)(paths.codexHome, "app-server-control", "app-server-control.sock"); return { action: "status", bridgePath: paths.bridgePath, @@ -22739,6 +24074,9 @@ ts() { date -u +%Y-%m-%dT%H:%M:%SZ; } wrapperPresent }; } + __webpack_require__.d(__webpack_exports__, { + em: ()=>desktopShimStatus + }); }, "./src/core/gateway.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { var node_crypto__rspack_import_0 = __webpack_require__("node:crypto"); @@ -24252,37 +25590,47 @@ function __webpack_require__(moduleId) { var __webpack_exports__ = {}; var node_worker_threads__rspack_import_0 = __webpack_require__("node:worker_threads"); var react__rspack_import_1 = __webpack_require__("./node_modules/react/react.react-server.js"); -var _agent_bundle_runtime_flight_server__rspack_import_19 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); -var _agent_bundle_runtime__rspack_import_16 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); -var _agent_bundle_runtime__rspack_import_17 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); -var _agent_bundle_runtime__rspack_import_18 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); +var _agent_bundle_runtime_flight_server__rspack_import_24 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); +var _agent_bundle_runtime__rspack_import_21 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); +var _agent_bundle_runtime__rspack_import_22 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); +var _agent_bundle_runtime__rspack_import_23 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); var node_url__rspack_import_2 = __webpack_require__("node:url"); -var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_3 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); -var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_4 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); -var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); -var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); -var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); -var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); -var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); -var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); -var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); -var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); -var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); -var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); -var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); -const route0 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_3, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_3); -const route1 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_4, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_4); -const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_5); -const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_6); -const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_7); -const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_8); -const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_9); -const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_10); -const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_11); -const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_12); -const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_13); -const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_14); -const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_15); +var _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); +var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); +var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); +var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); +var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); +var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); +var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); +var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); +var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); +var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); +var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); +var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); +var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); +var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); +const route0 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3); +const route1 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4); +const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_5); +const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_6); +const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_7); +const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_8); +const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_9); +const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_10); +const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_11); +const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_12); +const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_13); +const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_14); +const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_15); +const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_16); +const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_17); +const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_18); +const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_19); +const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_20); globalThis.__rspack_rsc_manifest__ ??= Object.freeze({ clientManifest: Object.freeze({}) }); @@ -24294,12 +25642,168 @@ const processLifetime = { instanceId: crypto.randomUUID(), pid: process.pid }; -const pluginRoot = (0, _agent_bundle_runtime__rspack_import_16.E7)({ +const pluginRoot = (0, _agent_bundle_runtime__rspack_import_21.E7)({ fallback: (0, node_url__rspack_import_2.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); const composeLayouts = (route, props)=>(0, react__rspack_import_1.createElement)(route.module.default, props); const routes = Object.freeze({ + "tool:grok-bot/chatgpt_desktop_list_threads": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend \"cdp\" or \"app-server\".", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum threads (1-200).", + "type": "number" + }, + "port": { + "type": "number" + } + }, + "required": [], + "type": "object" + }, + "title": "ChatGPT Desktop list threads" + }, + id: "tool:grok-bot/chatgpt_desktop_list_threads", + kind: "tool", + module: route0, + name: "chatgpt_desktop_list_threads", + serverId: "mcp:grok-bot" + }), + "tool:grok-bot/chatgpt_desktop_read_thread": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "port": { + "type": "number" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "type": "object" + }, + "title": "ChatGPT Desktop read thread" + }, + id: "tool:grok-bot/chatgpt_desktop_read_thread", + kind: "tool", + module: route1, + name: "chatgpt_desktop_read_thread", + serverId: "mcp:grok-bot" + }), + "tool:grok-bot/chatgpt_desktop_send": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": false + }, + "description": "EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "port": { + "type": "number" + }, + "text": { + "type": "string" + }, + "threadId": { + "description": "Sidebar thread id; omit to start/use a new chat.", + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "render": { + "maxElapsedMs": 120000 + }, + "title": "ChatGPT Desktop send" + }, + id: "tool:grok-bot/chatgpt_desktop_send", + kind: "tool", + module: route2, + name: "chatgpt_desktop_send", + serverId: "mcp:grok-bot" + }), + "tool:grok-bot/chatgpt_desktop_status": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "port": { + "description": "Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).", + "type": "number" + } + }, + "required": [], + "type": "object" + }, + "title": "ChatGPT Desktop status" + }, + id: "tool:grok-bot/chatgpt_desktop_status", + kind: "tool", + module: route3, + name: "chatgpt_desktop_status", + serverId: "mcp:grok-bot" + }), + "tool:grok-bot/chatgpt_desktop_wait_reply": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "port": { + "type": "number" + }, + "threadId": { + "type": "string" + }, + "timeoutMs": { + "type": "number" + } + }, + "required": [ + "threadId" + ], + "type": "object" + }, + "render": { + "maxElapsedMs": 660000 + }, + "title": "ChatGPT Desktop wait for reply" + }, + id: "tool:grok-bot/chatgpt_desktop_wait_reply", + kind: "tool", + module: route4, + name: "chatgpt_desktop_wait_reply", + serverId: "mcp:grok-bot" + }), "tool:grok-bot/claude_send": Object.freeze({ config: { "annotations": { @@ -24332,7 +25836,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/claude_send", kind: "tool", - module: route0, + module: route5, name: "claude_send", serverId: "mcp:grok-bot" }), @@ -24413,7 +25917,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_send", kind: "tool", - module: route1, + module: route6, name: "codex_send", serverId: "mcp:grok-bot" }), @@ -24447,7 +25951,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_threads", kind: "tool", - module: route2, + module: route7, name: "codex_threads", serverId: "mcp:grok-bot" }), @@ -24497,7 +26001,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_wait", kind: "tool", - module: route3, + module: route8, name: "codex_wait", serverId: "mcp:grok-bot" }), @@ -24540,7 +26044,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_watch", kind: "tool", - module: route4, + module: route9, name: "codex_watch", serverId: "mcp:grok-bot" }), @@ -24582,7 +26086,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_bridge_start", kind: "tool", - module: route5, + module: route10, name: "gbot_bridge_start", serverId: "mcp:grok-bot" }), @@ -24608,7 +26112,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_bridge_status", kind: "tool", - module: route6, + module: route11, name: "gbot_bridge_status", serverId: "mcp:grok-bot" }), @@ -24637,7 +26141,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_bridge_stop", kind: "tool", - module: route7, + module: route12, name: "gbot_bridge_stop", serverId: "mcp:grok-bot" }), @@ -24696,7 +26200,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_codex_respond", kind: "tool", - module: route8, + module: route13, name: "gbot_codex_respond", serverId: "mcp:grok-bot" }), @@ -24727,7 +26231,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_grok_approvals", kind: "tool", - module: route9, + module: route14, name: "gbot_grok_approvals", serverId: "mcp:grok-bot" }), @@ -24774,7 +26278,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_grok_respond", kind: "tool", - module: route10, + module: route15, name: "gbot_grok_respond", serverId: "mcp:grok-bot" }), @@ -24835,7 +26339,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_send", kind: "tool", - module: route11, + module: route16, name: "gbot_send", serverId: "mcp:grok-bot" }), @@ -24881,7 +26385,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_thread", kind: "tool", - module: route12, + module: route17, name: "gbot_thread", serverId: "mcp:grok-bot" }) @@ -24929,7 +26433,7 @@ const render = async (message)=>{ }; try { const plugin = message.plugin ?? pluginRoot.identity; - await (0, _agent_bundle_runtime__rspack_import_17.iC)({ + await (0, _agent_bundle_runtime__rspack_import_22.iC)({ ...message.actor === undefined ? {} : { actor: message.actor }, @@ -24943,7 +26447,7 @@ const render = async (message)=>{ operationId: route.id, surface: route.name }, - lineage: message.lineage ?? (0, _agent_bundle_runtime__rspack_import_17.hU)('not-provided'), + lineage: message.lineage ?? (0, _agent_bundle_runtime__rspack_import_22.hU)('not-provided'), plugin, progress: { report: async (update)=>{ @@ -24959,7 +26463,7 @@ const render = async (message)=>{ session: message.session }, signal: controller.signal, - terminal: message.terminal ?? (0, _agent_bundle_runtime__rspack_import_17.hU)('not-provided'), + terminal: message.terminal ?? (0, _agent_bundle_runtime__rspack_import_22.hU)('not-provided'), ...message.workspace === undefined ? {} : { workspace: message.workspace } @@ -24994,10 +26498,10 @@ const render = async (message)=>{ type: 'observed-render-start' }); const renderStartedAt = performance.now(); - const element = validationError === undefined ? composeLayouts(observedRoute, props, controller.signal) : (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_18.g.Result, null, (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_18.g.Error, { + const element = validationError === undefined ? composeLayouts(observedRoute, props, controller.signal) : (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_23.g.Result, null, (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_23.g.Error, { code: 'invalid-input' }, `Input validation error: ${validationError instanceof Error ? validationError.message : String(validationError)}`)); - const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_19.y)(element, { + const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_24.y)(element, { signal: controller.signal }); const reader = flight.getReader(); diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index adf82bd..9a76a11 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -6492,6 +6492,1108 @@ var __webpack_modules__ = { module.exports = __webpack_require__("./node_modules/react/cjs/react-jsx-runtime.development.js"); } }, + "./src/core/chatgpt-desktop/app-server-fallback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); + async function appServerListThreads({ limit = 50 } = {}) { + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit + }); + return { + backend: 'app-server', + limit: out.limit, + threads: out.threads.map((thread)=>({ + threadId: String(thread.id ?? ''), + title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), + pinned: false, + selected: false, + kind: 'codex' + })) + }; + } + async function appServerReadThread({ threadId, limit = 100 }) { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + let turns = []; + try { + const read = await client.request('thread/read', { + threadId + }); + const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; + turns = normalizeTurns(raw).slice(-limit); + } catch { + const items = await client.request('thread/items/list', { + threadId, + limit: Math.min(limit, 100) + }); + turns = normalizeTurns(items.data ?? []).slice(-limit); + } + return { + threadId, + turns, + backend: 'app-server', + limit + }; + } finally{ + client.close(); + } + } + async function appServerSendMessage({ threadId, text }) { + if (!threadId) { + return { + threadId: 'new', + backend: 'app-server', + experimental: false, + delivery: 'rejected', + message: 'app-server fallback requires an existing threadId; starting a new Desktop thread needs CDP' + }; + } + const receipt = await (0, _codex_bridge_js__rspack_import_0.ZS)(threadId, text); + return { + threadId, + backend: 'app-server', + experimental: false, + delivery: receipt.delivery ?? 'accepted', + message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined + }; + } + async function appServerWaitForReply({ threadId, timeoutMs = 60000 }) { + const baseline = await appServerReadThread({ + threadId, + limit: 200 + }); + const seen = new Set(baseline.turns.map((turn)=>turn.turnKey)); + const deadline = Date.now() + timeoutMs; + while(Date.now() < deadline){ + await new Promise((resolve)=>setTimeout(resolve, 400)); + const page = await appServerReadThread({ + threadId, + limit: 200 + }); + const fresh = page.turns.filter((turn)=>!seen.has(turn.turnKey) && turn.role === 'assistant' && turn.text); + const reply = fresh.at(-1)?.text ?? ''; + if (reply) { + return { + threadId, + reply, + backend: 'app-server', + experimental: false, + delivery: 'replied' + }; + } + } + return { + threadId, + reply: '', + backend: 'app-server', + experimental: false, + delivery: 'timeout' + }; + } + async function appServerOpenThread(threadId) { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + await client.request('thread/resume', { + threadId, + excludeTurns: true + }); + return { + threadId, + backend: 'app-server' + }; + } finally{ + client.close(); + } + } + async function appServerStatusProbe() { + const status = await (0, _codex_bridge_js__rspack_import_0.MU)(); + return { + reachable: Boolean(status.reachable && status.mode === 'daemon'), + mode: typeof status.mode === 'string' ? status.mode : undefined, + socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined + }; + } + function normalizeTurns(raw) { + const turns = []; + for (const [index, item] of raw.entries()){ + if (!item || typeof item !== 'object') continue; + const row = item; + const text = typeof row.text === 'string' ? row.text : typeof row.content === 'string' ? row.content : ''; + const type = String(row.type ?? row.role ?? ''); + let role = 'assistant'; + if (/user/i.test(type)) role = 'user'; + else if (/status|system|reasoning/i.test(type) && !text) role = 'status'; + turns.push({ + turnKey: String(row.id ?? row.turnId ?? index), + role, + text + }); + } + return turns; + } + __webpack_require__.d(__webpack_exports__, { + Ab: ()=>appServerSendMessage, + Jf: ()=>appServerReadThread, + OI: ()=>appServerListThreads, + bk: ()=>appServerWaitForReply, + dM: ()=>appServerStatusProbe, + zu: ()=>appServerOpenThread + }); + }, + "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _cdp_session_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); + var _cdp_dom_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); + var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + class CdpChatGptDesktopAdapter { + #port = (0, _loopback_js__rspack_import_3.L0)(); + #session = null; + #version = null; + #pageSessionId = null; + #mainTargetId = null; + async connect({ port }) { + await this.close(); + this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + const session = new _cdp_session_js__rspack_import_1.a(this.#port); + try { + this.#version = await session.connect(); + this.#session = session; + await this.#attachMainWindow(); + } catch (error) { + session.close(); + this.#session = null; + throw error; + } + } + async listTargets() { + const session = this.#requireSession(); + const result = await session.send('Target.getTargets'); + return (0, _cdp_dom_js__rspack_import_2.Mr)(result.targetInfos ?? []); + } + async listThreads({ limit = 50 } = {}) { + const sessionId = await this.#ensurePageSession(); + const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + limit + }); + return { + threads, + backend: 'cdp', + limit + }; + } + async readThread({ threadId, limit = 100 }) { + const sessionId = await this.#ensurePageSession(); + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await delay(150); + const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + limit + }); + return { + threadId, + turns, + backend: 'cdp', + limit + }; + } + async sendMessage({ threadId, text }) { + const sessionId = await this.#ensurePageSession(); + if (threadId) { + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await delay(100); + } + await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + return { + threadId: threadId ?? 'new', + backend: 'cdp', + experimental: true, + delivery: 'accepted', + message: 'Submitted via experimental CDP composer path' + }; + } + async waitForReply({ threadId, timeoutMs = 60000 }) { + const sessionId = await this.#ensurePageSession(); + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + const deadline = Date.now() + timeoutMs; + let previousKeys = new Set(); + let lastAssistant = ''; + let stable = 0; + const baseline = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + limit: 500 + }); + previousKeys = new Set(baseline.map((t)=>t.turnKey)); + while(Date.now() < deadline){ + await delay(400); + const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + limit: 500 + }); + const fresh = turns.filter((t)=>!previousKeys.has(t.turnKey) && t.role === 'assistant'); + const candidate = fresh.at(-1)?.text ?? ''; + if (candidate && candidate === lastAssistant) { + stable += 1; + if (stable >= 3) { + return { + threadId, + reply: candidate, + backend: 'cdp', + experimental: true, + delivery: 'replied' + }; + } + } else if (candidate) { + lastAssistant = candidate; + stable = 0; + } + } + return { + threadId, + reply: lastAssistant, + backend: 'cdp', + experimental: true, + delivery: lastAssistant ? 'replied' : 'timeout' + }; + } + async openThread(threadId) { + const sessionId = await this.#ensurePageSession(); + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + return { + threadId, + backend: 'cdp' + }; + } + async status() { + try { + const version = this.#version ?? await _cdp_session_js__rspack_import_1.a.fetchVersion(this.#port); + let targetCount; + let mainWindowTargetId; + if (this.#session && !this.#session.closed) { + const targets = await this.listTargets(); + targetCount = targets.length; + mainWindowTargetId = (0, _cdp_dom_js__rspack_import_2.C2)(targets)?.targetId ?? null; + } else { + const list = await _cdp_session_js__rspack_import_1.a.fetchJsonList(this.#port); + targetCount = list.length; + } + return { + reachable: true, + port: this.#port, + host: '127.0.0.1', + browser: typeof version.Browser === 'string' ? version.Browser : undefined, + protocolVersion: typeof version['Protocol-Version'] === 'string' ? version['Protocol-Version'] : undefined, + webSocketDebuggerUrl: typeof version.webSocketDebuggerUrl === 'string' ? version.webSocketDebuggerUrl : undefined, + targetCount, + mainWindowTargetId: mainWindowTargetId ?? this.#mainTargetId, + message: 'ChatGPT Desktop CDP endpoint reachable on 127.0.0.1', + exitCode: 0 + }; + } catch (error) { + return { + reachable: false, + port: this.#port, + host: '127.0.0.1', + message: error instanceof Error ? error.message : 'ChatGPT Desktop CDP endpoint unreachable on 127.0.0.1', + exitCode: 1 + }; + } + } + async close() { + this.#pageSessionId = null; + this.#mainTargetId = null; + this.#version = null; + this.#session?.close(); + this.#session = null; + } + async #attachMainWindow() { + const targets = await this.listTargets(); + const main = (0, _cdp_dom_js__rspack_import_2.C2)(targets); + if (!main) { + throw new _errors_js__rspack_import_0.sO(`No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`); + } + const attached = await this.#requireSession().send('Target.attachToTarget', { + targetId: main.targetId, + flatten: true + }); + this.#mainTargetId = main.targetId; + this.#pageSessionId = attached.sessionId; + } + async #ensurePageSession() { + this.#requireSession(); + if (!this.#pageSessionId) await this.#attachMainWindow(); + if (!this.#pageSessionId) { + throw new _errors_js__rspack_import_0.sO('Failed to attach to ChatGPT Desktop main window'); + } + return this.#pageSessionId; + } + #requireSession() { + if (!this.#session || this.#session.closed) { + throw new _errors_js__rspack_import_0.sO('Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.'); + } + return this.#session; + } + } + function delay(ms) { + return new Promise((resolve)=>setTimeout(resolve, ms)); + } + __webpack_require__.d(__webpack_exports__, { + a: ()=>CdpChatGptDesktopAdapter + }); + }, + "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + const MAIN_WINDOW_URL = 'app://-/index.html'; + const ATTR = { + threadRow: 'data-app-action-sidebar-thread-row', + threadId: 'data-app-action-sidebar-thread-id', + threadTitle: 'data-app-action-sidebar-thread-title', + threadPinned: 'data-app-action-sidebar-thread-pinned', + threadSelected: 'data-app-action-sidebar-thread-selected', + threadKind: 'data-app-action-sidebar-thread-kind', + turnKey: 'data-turn-key', + userBubble: 'data-user-message-bubble', + timelineScroll: 'data-app-action-timeline-scroll', + virtualizedTurn: 'data-virtualized-turn-content' + }; + const SELECTORS = { + threadRow: `[role="button"][${ATTR.threadRow}]`, + turn: `[${ATTR.turnKey}]`, + userBubble: `[${ATTR.userBubble}]`, + timelineScroll: `[${ATTR.timelineScroll}]`, + mainSurface: 'main', + composerCandidates: [ + 'main [contenteditable="true"]', + 'main textarea', + '[data-app-action-composer] [contenteditable="true"]', + '[data-app-action-composer] textarea', + 'form [contenteditable="true"]', + 'form textarea' + ], + sendButtonCandidates: [ + 'button[data-app-action-send]', + 'button[aria-label="Send"]', + 'button[aria-label="Send message"]', + 'main button[type="submit"]' + ] + }; + function isMainWindowTarget(target) { + return target.type === 'page' && target.url === MAIN_WINDOW_URL; + } + function summarizeTargetInfos(targetInfos) { + return targetInfos.filter((t)=>typeof t.targetId === 'string' && typeof t.type === 'string').map((t)=>({ + targetId: String(t.targetId), + type: String(t.type), + title: typeof t.title === 'string' ? t.title : '', + url: typeof t.url === 'string' ? t.url : '', + attached: Boolean(t.attached) + })); + } + function pickMainWindowTarget(targets) { + return targets.find((t)=>isMainWindowTarget(t)) ?? null; + } + const LIST_THREADS_EXPRESSION = `(() => { + const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); + return rows.map((row) => ({ + threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || '', + title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), + pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', + selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', + kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + })).filter((t) => t.threadId); +})()`; + function openThreadExpression(threadId) { + return `(() => { + const id = ${JSON.stringify(threadId)}; + const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); + const row = rows.find((el) => el.getAttribute(${JSON.stringify(ATTR.threadId)}) === id); + if (!row) return { ok: false, error: 'thread-not-found' }; + row.click(); + return { ok: true, threadId: id }; + })()`; + } + const READ_THREAD_EXPRESSION = `(() => { + const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + const mains = Array.from(document.querySelectorAll('main')); + const surface = mains.length >= 2 ? mains[1] : (mains[0] || document.body); + const root = scroll || surface; + const collected = new Map(); + const statusRe = /^Worked for \\d+s$/i; + const harvest = () => { + for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { + const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; + if (!turnKey || collected.has(turnKey)) continue; + const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); + const text = (el.innerText || '').trim(); + let role = 'assistant'; + if (user) role = 'user'; + else if (!text || statusRe.test(text)) role = 'status'; + collected.set(turnKey, { turnKey, role, text }); + } + }; + const maxPasses = 80; + let stable = 0; + let lastSize = -1; + if (scroll) scroll.scrollTop = 0; + for (let i = 0; i < maxPasses; i++) { + harvest(); + if (collected.size === lastSize) { + stable += 1; + if (stable >= 3) break; + } else { + stable = 0; + lastSize = collected.size; + } + if (scroll) { + const next = Math.min(scroll.scrollHeight, scroll.scrollTop + Math.max(scroll.clientHeight, 200)); + if (next <= scroll.scrollTop && stable >= 1) break; + scroll.scrollTop = next; + } else { + break; + } + } + harvest(); + return Array.from(collected.values()); +})()`; + function sendMessageExpression(text) { + const composers = JSON.stringify([ + ...SELECTORS.composerCandidates + ]); + const buttons = JSON.stringify([ + ...SELECTORS.sendButtonCandidates + ]); + return `(() => { + const text = ${JSON.stringify(text)}; + const composers = ${composers}; + let composer = null; + for (const sel of composers) { + composer = document.querySelector(sel); + if (composer) break; + } + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.focus(); + if (composer.isContentEditable) { + composer.textContent = text; + composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: text, inputType: 'insertText' })); + } else if ('value' in composer) { + composer.value = text; + composer.dispatchEvent(new Event('input', { bubbles: true })); + } else { + return { ok: false, error: 'composer-unsupported' }; + } + const buttons = ${buttons}; + let sent = false; + for (const sel of buttons) { + const btn = document.querySelector(sel); + if (btn && !btn.disabled) { btn.click(); sent = true; break; } + } + if (!sent) { + composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true })); + composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', bubbles: true })); + } + return { ok: true, sentVia: sent ? 'button' : 'enter' }; + })()`; + } + async function listThreadsFromDom(session, sessionId, { limit = 50 } = {}) { + const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { + sessionId + }); + if (!Array.isArray(rows)) return []; + return rows.slice(0, limit).map((row)=>({ + threadId: String(row.threadId), + title: String(row.title ?? ''), + pinned: Boolean(row.pinned), + selected: Boolean(row.selected), + kind: String(row.kind ?? 'unknown') + })); + } + async function openThreadInDom(session, sessionId, threadId) { + const result = await session.evaluate(openThreadExpression(threadId), { + sessionId + }); + if (!result?.ok) { + throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); + } + } + async function readTurnsFromDom(session, sessionId, { limit = 100 } = {}) { + const turns = await session.evaluate(READ_THREAD_EXPRESSION, { + sessionId + }); + if (!Array.isArray(turns)) return []; + return turns.slice(-limit).map((turn)=>({ + turnKey: String(turn.turnKey), + role: turn.role === 'user' || turn.role === 'status' ? turn.role : 'assistant', + text: String(turn.text ?? '') + })); + } + async function sendMessageInDom(session, sessionId, text) { + try { + await session.send('Input.insertText', { + text + }, { + sessionId + }); + } catch {} + const result = await session.evaluate(sendMessageExpression(text), { + sessionId + }); + if (!result?.ok) { + throw new Error(result?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${result?.error ?? 'unknown'}`); + } + return { + sentVia: result.sentVia ?? 'unknown' + }; + } + __webpack_require__.d(__webpack_exports__, { + AY: ()=>listThreadsFromDom, + C2: ()=>pickMainWindowTarget, + JU: ()=>readTurnsFromDom, + Kl: ()=>openThreadInDom, + Mr: ()=>summarizeTargetInfos, + lh: ()=>sendMessageInDom + }); + }, + "./src/core/chatgpt-desktop/cdp-session.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _loopback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + class CdpSession { + #port; + #ws = null; + #nextId = 1; + #pending = new Map(); + #closed = false; + constructor(port){ + this.#port = port; + } + get port() { + return this.#port; + } + get closed() { + return this.#closed || this.#ws === null || this.#ws.readyState === WebSocket.CLOSED; + } + static async fetchVersion(port, { signal } = {}) { + const base = (0, _loopback_js__rspack_import_1.NJ)(port); + let response; + try { + response = await fetch(`${base}/json/version`, { + signal + }); + } catch (error) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/version: ` + (error instanceof Error ? error.message : String(error))); + } + if (!response.ok) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP /json/version returned HTTP ${response.status}`); + } + return await response.json(); + } + static async fetchJsonList(port, { signal } = {}) { + const base = (0, _loopback_js__rspack_import_1.NJ)(port); + let response; + try { + response = await fetch(`${base}/json/list`, { + signal + }); + } catch (error) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/list: ` + (error instanceof Error ? error.message : String(error))); + } + if (!response.ok) { + throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP /json/list returned HTTP ${response.status}`); + } + const body = await response.json(); + return Array.isArray(body) ? body : []; + } + async connect({ signal } = {}) { + if (this.#ws && !this.closed) { + throw new Error('CDP session already connected'); + } + const version = await CdpSession.fetchVersion(this.#port, { + signal + }); + const rawUrl = version.webSocketDebuggerUrl; + if (typeof rawUrl !== 'string' || !rawUrl) { + throw new _errors_js__rspack_import_0.sO('CDP /json/version omitted webSocketDebuggerUrl'); + } + const url = (0, _loopback_js__rspack_import_1.jv)(rawUrl); + const parsed = new URL(url); + (0, _loopback_js__rspack_import_1.tb)(parsed.hostname); + await new Promise((resolve, reject)=>{ + const ws = new WebSocket(url); + this.#ws = ws; + const onAbort = ()=>{ + ws.close(); + reject(new Error('CDP connect aborted')); + }; + signal?.addEventListener('abort', onAbort, { + once: true + }); + ws.addEventListener('open', ()=>{ + signal?.removeEventListener('abort', onAbort); + resolve(); + }, { + once: true + }); + ws.addEventListener('error', ()=>{ + signal?.removeEventListener('abort', onAbort); + reject(new _errors_js__rspack_import_0.sO(`CDP WebSocket failed for ${url}`)); + }, { + once: true + }); + ws.addEventListener('message', (event)=>this.#onMessage(event.data)); + ws.addEventListener('close', ()=>{ + this.#closed = true; + for (const [, pending] of this.#pending){ + pending.reject(new Error('CDP WebSocket closed')); + } + this.#pending.clear(); + }); + }); + this.#closed = false; + return version; + } + async send(method, params, { sessionId } = {}) { + if (!this.#ws || this.#ws.readyState !== WebSocket.OPEN) { + throw new _errors_js__rspack_import_0.sO('CDP session is not connected'); + } + const id = this.#nextId++; + const payload = { + id, + method + }; + if (params !== undefined) payload.params = params; + if (sessionId !== undefined) payload.sessionId = sessionId; + return await new Promise((resolve, reject)=>{ + this.#pending.set(id, { + resolve: (value)=>resolve(value), + reject + }); + this.#ws.send(JSON.stringify(payload)); + }); + } + async evaluate(expression, { sessionId, awaitPromise = true } = {}) { + const result = await this.send('Runtime.evaluate', { + expression, + returnByValue: true, + awaitPromise + }, { + sessionId + }); + if (result.exceptionDetails) { + const text = result.exceptionDetails.exception?.description || result.exceptionDetails.text || 'Runtime.evaluate failed'; + throw new Error(text); + } + return result.result?.value; + } + close() { + this.#closed = true; + this.#ws?.close(); + this.#ws = null; + } + #onMessage(data) { + let message; + try { + message = JSON.parse(String(data)); + } catch { + return; + } + if (typeof message.id !== 'number') return; + const pending = this.#pending.get(message.id); + if (!pending) return; + this.#pending.delete(message.id); + if (message.error) { + pending.reject(new Error(message.error.message || 'CDP error')); + return; + } + pending.resolve(message.result); + } + } + __webpack_require__.d(__webpack_exports__, { + a: ()=>CdpSession + }); + }, + "./src/core/chatgpt-desktop/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + class NotImplementedError extends Error { + code = 'NOT_IMPLEMENTED'; + delivery = 'rejected'; + reason = 'not-implemented'; + constructor(operation, detail){ + super(detail ? `ChatGPT Desktop ${operation} is not implemented: ${detail}` : `ChatGPT Desktop ${operation} is not implemented`); + this.name = 'NotImplementedError'; + } + } + class CdpHostRejectedError extends Error { + code = 'CDP_HOST_REJECTED'; + delivery = 'rejected'; + reason = 'cdp-host-rejected'; + constructor(host){ + super(`ChatGPT Desktop CDP rejects non-loopback host ${JSON.stringify(host)}. ` + 'Connect to 127.0.0.1 only; there is no remote transport.'); + this.name = 'CdpHostRejectedError'; + } + } + class CdpUnreachableError extends Error { + code = 'CDP_UNREACHABLE'; + delivery = 'rejected'; + reason = 'cdp-unreachable'; + constructor(message){ + super(message); + this.name = 'CdpUnreachableError'; + } + } + __webpack_require__.d(__webpack_exports__, { + EH: ()=>NotImplementedError, + c$: ()=>CdpHostRejectedError, + sO: ()=>CdpUnreachableError + }); + }, + "./src/core/chatgpt-desktop/facade.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _cdp_adapter_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-adapter.ts"); + var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); + var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + class ChatGptDesktopFacade { + #cdp; + #port; + #cdpConnected = false; + constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)()){ + this.#cdp = cdp; + this.#port = port; + } + async connect({ port }) { + this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + try { + await this.#cdp.connect({ + port: this.#port + }); + this.#cdpConnected = true; + } catch (error) { + this.#cdpConnected = false; + throw error; + } + } + async listTargets() { + await this.#ensureCdp(); + return this.#cdp.listTargets(); + } + async listThreads(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.listThreads(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.OI)(options); + } + } + async readThread(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.readThread(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.Jf)(options); + } + } + async sendMessage(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.sendMessage(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.Ab)(options); + } + } + async waitForReply(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.waitForReply(options); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.bk)(options); + } + } + async openThread(threadId) { + try { + await this.#ensureCdp(); + return await this.#cdp.openThread(threadId); + } catch (error) { + if (!isCdpFailure(error)) throw error; + return (0, _app_server_fallback_js__rspack_import_1.zu)(threadId); + } + } + async status() { + const cdpStatus = await this.#cdp.status(); + let appServerFallback; + try { + appServerFallback = await (0, _app_server_fallback_js__rspack_import_1.dM)(); + } catch { + appServerFallback = { + reachable: false + }; + } + const reachable = cdpStatus.reachable || Boolean(appServerFallback?.reachable); + return { + ...cdpStatus, + port: this.#port, + appServerFallback, + reachable, + message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server fallback is available' : cdpStatus.message, + exitCode: reachable ? 0 : 1 + }; + } + async close() { + this.#cdpConnected = false; + await this.#cdp.close(); + } + async #ensureCdp() { + if (this.#cdpConnected) return; + await this.#cdp.connect({ + port: this.#port + }); + this.#cdpConnected = true; + } + } + function isCdpFailure(error) { + if (error instanceof _errors_js__rspack_import_2.sO) return true; + if (error instanceof _errors_js__rspack_import_2.EH) return false; + if (error && typeof error === 'object' && 'code' in error) { + const code = String(error.code); + return code === 'CDP_UNREACHABLE' || code === 'CDP_HOST_REJECTED'; + } + return false; + } + let activeAdapter = null; + function getChatGptDesktopAdapter() { + if (!activeAdapter) activeAdapter = new ChatGptDesktopFacade(); + return activeAdapter; + } + function setChatGptDesktopAdapterForTests(adapter) { + activeAdapter = adapter; + } + __webpack_require__.d(__webpack_exports__, { + PP: ()=>getChatGptDesktopAdapter + }); + }, + "./src/core/chatgpt-desktop/loopback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + const LOOPBACK = new Set([ + '127.0.0.1', + 'localhost', + '::1' + ]); + const DEFAULT_CDP_PORT = 9222; + const CDP_LOOPBACK_HOST = '127.0.0.1'; + function isLoopbackHostname(hostname) { + const host = String(hostname || '').toLowerCase().replace(/^\[|\]$/g, ''); + return LOOPBACK.has(host); + } + function assertLoopbackHostname(hostname) { + if (!isLoopbackHostname(hostname)) { + throw new _errors_js__rspack_import_0.c$(hostname); + } + } + function cdpHttpBase(port) { + if (!Number.isInteger(port) || port < 1 || port > 65535) { + throw new RangeError('CDP port must be an integer 1-65535'); + } + return `http://${CDP_LOOPBACK_HOST}:${port}`; + } + function forceLoopbackWebSocketUrl(raw) { + let url; + try { + url = new URL(raw); + } catch { + throw new _errors_js__rspack_import_0.c$(String(raw)); + } + assertLoopbackHostname(url.hostname); + if (url.protocol !== 'ws:' && url.protocol !== 'wss:') { + throw new Error(`Expected ws(s) debugger URL, got ${url.protocol}`); + } + url.hostname = CDP_LOOPBACK_HOST; + url.protocol = 'ws:'; + return url.toString(); + } + function resolveCdpPort(env = process.env, explicit) { + if (explicit !== undefined) { + if (!Number.isInteger(explicit) || explicit < 1 || explicit > 65535) { + throw new RangeError('CDP port must be an integer 1-65535'); + } + return explicit; + } + const raw = (env.CHATGPT_DESKTOP_CDP_PORT || '').trim(); + if (!raw) return DEFAULT_CDP_PORT; + const port = Number.parseInt(raw, 10); + if (!Number.isInteger(port) || port < 1 || port > 65535) { + throw new RangeError('CHATGPT_DESKTOP_CDP_PORT must be an integer 1-65535'); + } + return port; + } + __webpack_require__.d(__webpack_exports__, { + L0: ()=>resolveCdpPort, + NJ: ()=>cdpHttpBase, + jv: ()=>forceLoopbackWebSocketUrl, + tb: ()=>assertLoopbackHostname + }); + }, + "./src/core/chatgpt-desktop/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var zod__rspack_import_4 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _codex_contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); + var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _facade_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/facade.ts"); + var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + const threadId = zod__rspack_import_4.YjP().min(1).max(256); + const statusSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional() + }).strict(); + const listThreadsSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + }).strict(); + const readThreadSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId, + limit: zod__rspack_import_4.aig().int().min(1).max(500).default(100) + }).strict(); + const sendSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId: threadId.optional(), + text: zod__rspack_import_4.YjP().min(1).max(100000) + }).strict(); + const waitReplySchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId, + timeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(60000) + }).strict(); + const resultSchema = zod__rspack_import_4.Ikc({ + exitCode: zod__rspack_import_4.KCZ([ + zod__rspack_import_4.euz(0), + zod__rspack_import_4.euz(1) + ]) + }).catchall(zod__rspack_import_4.Pq9()); + async function withAdapter(port, run) { + const adapter = (0, _facade_js__rspack_import_2.PP)(); + const resolved = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + try { + await adapter.connect({ + port: resolved + }); + } catch {} + return run(adapter); + } + function asResult(value) { + return resultSchema.parse(value); + } + function mapError(error) { + if (error instanceof _errors_js__rspack_import_1.EH) { + return asResult({ + delivery: 'rejected', + reason: 'not-implemented', + code: 'NOT_IMPLEMENTED', + error: error.message, + exitCode: 1 + }); + } + const base = (0, _codex_contract_js__rspack_import_0.DG)(error); + if (error && typeof error === 'object' && 'code' in error) { + return asResult({ + ...base, + code: String(error.code) + }); + } + return asResult(base); + } + async function statusOperation(input) { + try { + const status = await withAdapter(input.port, (adapter)=>adapter.status()); + return asResult(status); + } catch (error) { + return mapError(error); + } + } + async function listThreadsOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ + limit: input.limit + })); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } + async function readThreadOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ + threadId: input.threadId, + limit: input.limit + })); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } + async function sendOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.sendMessage({ + threadId: input.threadId, + text: input.text + })); + return asResult({ + ...out, + exitCode: out.delivery === 'accepted' ? 0 : 1 + }); + } catch (error) { + return mapError(error); + } + } + async function waitReplyOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.waitForReply({ + threadId: input.threadId, + timeoutMs: input.timeoutMs + })); + return asResult({ + ...out, + exitCode: out.delivery === 'replied' ? 0 : 1 + }); + } catch (error) { + return mapError(error); + } + } + function resultText(result) { + if (result.error) return String(result.error); + if (result.reachable === true) { + const backend = result.appServerFallback && typeof result.appServerFallback === 'object' ? ` cdp + app-server probe` : ''; + return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; + } + if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); + if (Array.isArray(result.threads)) { + return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; + } + if (Array.isArray(result.turns)) { + return `${result.turns.length} turns on ${result.threadId} via ${result.backend ?? 'unknown'}`; + } + if (result.delivery === 'accepted') { + return `Sent on ${result.threadId} via ${result.backend}${result.experimental ? ' (experimental)' : ''}`; + } + if (result.delivery === 'replied') { + return String(result.reply ?? 'replied'); + } + if (result.delivery) return `delivery ${result.delivery}`; + return JSON.stringify(result); + } + __webpack_require__.d(__webpack_exports__, { + D6: ()=>resultText, + UK: ()=>readThreadOperation, + UP: ()=>sendOperation, + Uj: ()=>statusOperation, + Zg: ()=>waitReplyOperation, + tJ: ()=>listThreadsOperation + }, { + FC: listThreadsSchema, + FD: resultSchema, + Fn: waitReplySchema, + Wi: sendSchema, + aW: statusSchema, + so: readThreadSchema + }); + }, "./src/core/claude-routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_1 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _claude_channel_js__rspack_import_0 = __webpack_require__("./src/core/claude-channel.js"); @@ -7054,6 +8156,237 @@ var __webpack_modules__ = { yF: withRedactedErrors }); }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop list threads', + description: 'List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend "cdp" or "app-server".', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FC, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number' + }, + limit: { + type: 'number', + description: 'Maximum threads (1-200).' + } + }, + required: [] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.tJ)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.FC + }, { + "default": __rspack_default_export + }); + }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop read thread', + description: 'Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.so, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number' + }, + threadId: { + type: 'string' + }, + limit: { + type: 'number' + } + }, + required: [ + 'threadId' + ] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.UK)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.so + }, { + "default": __rspack_default_export + }); + }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop send', + description: 'EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.', + annotations: { + readOnlyHint: false + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.Wi, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + render: { + maxElapsedMs: 120000 + }, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number' + }, + threadId: { + type: 'string', + description: 'Sidebar thread id; omit to start/use a new chat.' + }, + text: { + type: 'string' + } + }, + required: [ + 'text' + ] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.UP)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.Wi + }, { + "default": __rspack_default_export + }); + }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop status', + description: 'Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.aW, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number', + description: 'Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).' + } + }, + required: [] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.Uj)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.aW + }, { + "default": __rspack_default_export + }); + }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop wait for reply', + description: 'EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.Fn, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + render: { + maxElapsedMs: 660000 + }, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number' + }, + threadId: { + type: 'string' + }, + timeoutMs: { + type: 'number' + } + }, + required: [ + 'threadId' + ] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.Zg)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.Fn + }, { + "default": __rspack_default_export + }); + }, "./src/mcp/grok-bot/tools/claude_send.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); @@ -56143,46 +57476,207 @@ var __webpack_modules__ = { "./.agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var node_url__rspack_import_0 = __webpack_require__("node:url"); - var _agent_bundle_runtime__rspack_import_16 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); + var _agent_bundle_runtime__rspack_import_21 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); var agent_bundle_mcp_server_runtime__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/mcp-server-runtime.js"); - var _agent_bundle_runtime_lineage__rspack_import_17 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/lineage.js"); + var _agent_bundle_runtime_lineage__rspack_import_22 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/lineage.js"); var agent_bundle_mcp_apps__rspack_import_2 = __webpack_require__("./.agent-bundle-virtual/mcp-grok-bot-b8c2461e-0.mjs"); - var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_3 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); - var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_4 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); - var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); - var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); - var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); - var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); - var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); - var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); - var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); - var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); - var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); - var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); - var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); - const route0 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_3, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_3); - const route1 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_4, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_4); - const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_5); - const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_6); - const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_7); - const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_8); - const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_9); - const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_10); - const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_11); - const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_12); - const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_13); - const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_14); - const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_15); + var _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); + var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); + var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); + var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); + var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); + var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); + var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); + var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); + var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); + var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); + var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); + var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); + var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); + var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); + const route0 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3); + const route1 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4); + const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_5); + const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_6); + const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_7); + const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_8); + const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_9); + const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_10); + const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_11); + const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_12); + const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_13); + const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_14); + const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_15); + const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_16); + const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_17); + const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_18); + const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_19); + const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_20); const ARTIFACT_EPOCH = "gbot@0.10.1"; - const pluginRoot = (0, _agent_bundle_runtime__rspack_import_16.E7)({ + const pluginRoot = (0, _agent_bundle_runtime__rspack_import_21.E7)({ fallback: (0, node_url__rspack_import_0.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); const openLineage = async ()=>({ dispose: async ()=>undefined, - registry: (0, _agent_bundle_runtime_lineage__rspack_import_17.Q5)() + registry: (0, _agent_bundle_runtime_lineage__rspack_import_22.Q5)() }); const routes = Object.freeze({ + "tool:grok-bot/chatgpt_desktop_list_threads": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend \"cdp\" or \"app-server\".", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum threads (1-200).", + "type": "number" + }, + "port": { + "type": "number" + } + }, + "required": [], + "type": "object" + }, + "title": "ChatGPT Desktop list threads" + }, + id: "tool:grok-bot/chatgpt_desktop_list_threads", + kind: "tool", + module: route0, + name: "chatgpt_desktop_list_threads" + }), + "tool:grok-bot/chatgpt_desktop_read_thread": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "port": { + "type": "number" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "type": "object" + }, + "title": "ChatGPT Desktop read thread" + }, + id: "tool:grok-bot/chatgpt_desktop_read_thread", + kind: "tool", + module: route1, + name: "chatgpt_desktop_read_thread" + }), + "tool:grok-bot/chatgpt_desktop_send": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": false + }, + "description": "EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "port": { + "type": "number" + }, + "text": { + "type": "string" + }, + "threadId": { + "description": "Sidebar thread id; omit to start/use a new chat.", + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "render": { + "maxElapsedMs": 120000 + }, + "title": "ChatGPT Desktop send" + }, + id: "tool:grok-bot/chatgpt_desktop_send", + kind: "tool", + module: route2, + name: "chatgpt_desktop_send" + }), + "tool:grok-bot/chatgpt_desktop_status": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "port": { + "description": "Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).", + "type": "number" + } + }, + "required": [], + "type": "object" + }, + "title": "ChatGPT Desktop status" + }, + id: "tool:grok-bot/chatgpt_desktop_status", + kind: "tool", + module: route3, + name: "chatgpt_desktop_status" + }), + "tool:grok-bot/chatgpt_desktop_wait_reply": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "port": { + "type": "number" + }, + "threadId": { + "type": "string" + }, + "timeoutMs": { + "type": "number" + } + }, + "required": [ + "threadId" + ], + "type": "object" + }, + "render": { + "maxElapsedMs": 660000 + }, + "title": "ChatGPT Desktop wait for reply" + }, + id: "tool:grok-bot/chatgpt_desktop_wait_reply", + kind: "tool", + module: route4, + name: "chatgpt_desktop_wait_reply" + }), "tool:grok-bot/claude_send": Object.freeze({ config: { "annotations": { @@ -56215,7 +57709,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/claude_send", kind: "tool", - module: route0, + module: route5, name: "claude_send" }), "tool:grok-bot/codex_send": Object.freeze({ @@ -56295,7 +57789,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_send", kind: "tool", - module: route1, + module: route6, name: "codex_send" }), "tool:grok-bot/codex_threads": Object.freeze({ @@ -56328,7 +57822,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_threads", kind: "tool", - module: route2, + module: route7, name: "codex_threads" }), "tool:grok-bot/codex_wait": Object.freeze({ @@ -56377,7 +57871,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_wait", kind: "tool", - module: route3, + module: route8, name: "codex_wait" }), "tool:grok-bot/codex_watch": Object.freeze({ @@ -56419,7 +57913,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_watch", kind: "tool", - module: route4, + module: route9, name: "codex_watch" }), "tool:grok-bot/gbot_bridge_start": Object.freeze({ @@ -56460,7 +57954,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_bridge_start", kind: "tool", - module: route5, + module: route10, name: "gbot_bridge_start" }), "tool:grok-bot/gbot_bridge_status": Object.freeze({ @@ -56485,7 +57979,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_bridge_status", kind: "tool", - module: route6, + module: route11, name: "gbot_bridge_status" }), "tool:grok-bot/gbot_bridge_stop": Object.freeze({ @@ -56513,7 +58007,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_bridge_stop", kind: "tool", - module: route7, + module: route12, name: "gbot_bridge_stop" }), "tool:grok-bot/gbot_codex_respond": Object.freeze({ @@ -56571,7 +58065,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_codex_respond", kind: "tool", - module: route8, + module: route13, name: "gbot_codex_respond" }), "tool:grok-bot/gbot_grok_approvals": Object.freeze({ @@ -56601,7 +58095,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_grok_approvals", kind: "tool", - module: route9, + module: route14, name: "gbot_grok_approvals" }), "tool:grok-bot/gbot_grok_respond": Object.freeze({ @@ -56647,7 +58141,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_grok_respond", kind: "tool", - module: route10, + module: route15, name: "gbot_grok_respond" }), "tool:grok-bot/gbot_send": Object.freeze({ @@ -56707,7 +58201,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_send", kind: "tool", - module: route11, + module: route16, name: "gbot_send" }), "tool:grok-bot/gbot_thread": Object.freeze({ @@ -56752,7 +58246,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_thread", kind: "tool", - module: route12, + module: route17, name: "gbot_thread" }) }); @@ -57934,7 +59428,7 @@ var __webpack_modules__ = { const openSession = openCodexSession; const CODEX_VERSION_PROBE_TIMEOUT_MS = 3000; function probeLocalCodexVersion(timeoutMs = CODEX_VERSION_PROBE_TIMEOUT_MS) { - const out = spawnSync("codex", [ + const out = (0, node_child_process__rspack_import_5.spawnSync)("codex", [ "--version" ], { encoding: "utf8", @@ -57967,7 +59461,7 @@ var __webpack_modules__ = { function listDesktopProcesses(timeoutMs = DESKTOP_PROCESS_LIST_TIMEOUT_MS) { if (process.platform === "win32") return ""; try { - const out = spawnSync("ps", [ + const out = (0, node_child_process__rspack_import_5.spawnSync)("ps", [ "-eo", "args" ], { @@ -57995,7 +59489,7 @@ var __webpack_modules__ = { let desktopShimConfigured = Boolean(shim && shim.installed && shim.wrapperPointsAtShim); if (shim === undefined) { try { - const live = desktopShimStatus({ + const live = (0, _desktop_shim_js__rspack_import_8.em)({ env }); desktopShimConfigured = Boolean(live.installed && live.wrapperPointsAtShim); @@ -58022,14 +59516,14 @@ var __webpack_modules__ = { } catch (err) { if (err instanceof CodexRouteError) { const message = err.mode === "socket-absent" ? unreachableMessage(path, desktopAttached, env) : err.message; - return withStatusExitCode({ + return (0, _codex_contract_js__rspack_import_7.AQ)({ ...base, reachable: false, mode: err.mode, message }); } - if (err instanceof CodexProtocolError) return withStatusExitCode({ + if (err instanceof CodexProtocolError) return (0, _codex_contract_js__rspack_import_7.AQ)({ ...base, reachable: true, mode: err.mode, @@ -58039,7 +59533,7 @@ var __webpack_modules__ = { } session.client.close(); const daemonVersion = appServerVersion(session.init); - return withStatusExitCode({ + return (0, _codex_contract_js__rspack_import_7.AQ)({ ...base, reachable: true, mode: "daemon", @@ -58550,6 +60044,7 @@ var __webpack_modules__ = { } __webpack_require__.d(__webpack_exports__, { $3: ()=>assertThreadAllowed, + MU: ()=>codexStatus, Mr: ()=>withEnvelopeHeader, X$: ()=>listCodexThreads, ZS: ()=>sendToCodexThread, @@ -58564,7 +60059,7 @@ var __webpack_modules__ = { function statusExitCode(status) { return status.reachable && status.mode === "daemon" ? 0 : 1; } - function withStatusExitCode1(status) { + function withStatusExitCode(status) { return { ...status, exitCode: statusExitCode(status) @@ -58620,6 +60115,7 @@ var __webpack_modules__ = { }; } __webpack_require__.d(__webpack_exports__, { + AQ: ()=>withStatusExitCode, DG: ()=>outcomeFromError, Dz: ()=>outcomeFromReceipt }); @@ -59061,7 +60557,7 @@ var __webpack_modules__ = { j: ()=>openCodexConversation }); }, - "./src/core/desktop-shim.js" (__unused_rspack___webpack_module__, __unused_rspack___webpack_exports__, __webpack_require__) { + "./src/core/desktop-shim.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { var node_child_process__rspack_import_0 = __webpack_require__("node:child_process"); var node_fs__rspack_import_1 = __webpack_require__("node:fs"); var node_os__rspack_import_2 = __webpack_require__("node:os"); @@ -59078,25 +60574,25 @@ var __webpack_modules__ = { return env.CODEX_HOME || join(env.HOME || homedir(), ".codex"); } function userHomeDir(env = process.env) { - return env.HOME || homedir(); + return env.HOME || (0, node_os__rspack_import_2.homedir)(); } function defaultPaths({ env = process.env, home = userHomeDir(env) } = {}) { - const codexHome = env.CODEX_HOME || join(home, ".codex"); - const binDir = join(codexHome, "bin"); + const codexHome = env.CODEX_HOME || (0, node_path__rspack_import_3.join)(home, ".codex"); + const binDir = (0, node_path__rspack_import_3.join)(codexHome, "bin"); return { binDir, - bridgeLogPath: join(binDir, BRIDGE_LOG_FILENAME), - bridgePath: join(binDir, BRIDGE_FILENAME), + bridgeLogPath: (0, node_path__rspack_import_3.join)(binDir, BRIDGE_LOG_FILENAME), + bridgePath: (0, node_path__rspack_import_3.join)(binDir, BRIDGE_FILENAME), codexHome, - envLogPath: join(binDir, ENV_LOG_FILENAME), - envScriptPath: join(binDir, ENV_SCRIPT_FILENAME), + envLogPath: (0, node_path__rspack_import_3.join)(binDir, ENV_LOG_FILENAME), + envScriptPath: (0, node_path__rspack_import_3.join)(binDir, ENV_SCRIPT_FILENAME), label: SHIM_LABEL, - launchAgentsDir: join(home, "Library", "LaunchAgents"), - plistPath: join(home, "Library", "LaunchAgents", `${SHIM_LABEL}.plist`), - realPath: join(codexHome, STANDALONE_REAL_SUFFIX), - socketPath: join(codexHome, "app-server-control", "app-server-control.sock"), - wrapperLogPath: join(binDir, WRAPPER_LOG_FILENAME), - wrapperPath: join(binDir, WRAPPER_FILENAME) + launchAgentsDir: (0, node_path__rspack_import_3.join)(home, "Library", "LaunchAgents"), + plistPath: (0, node_path__rspack_import_3.join)(home, "Library", "LaunchAgents", `${SHIM_LABEL}.plist`), + realPath: (0, node_path__rspack_import_3.join)(codexHome, STANDALONE_REAL_SUFFIX), + socketPath: (0, node_path__rspack_import_3.join)(codexHome, "app-server-control", "app-server-control.sock"), + wrapperLogPath: (0, node_path__rspack_import_3.join)(binDir, WRAPPER_LOG_FILENAME), + wrapperPath: (0, node_path__rspack_import_3.join)(binDir, WRAPPER_FILENAME) }; } function shouldBridge(argv) { @@ -59256,7 +60752,7 @@ ts() { date -u +%Y-%m-%dT%H:%M:%SZ; } } const defaultRunner = (file, args)=>{ try { - return spawnSync(file, args, { + return (0, node_child_process__rspack_import_0.spawnSync)(file, args, { encoding: "utf8", timeout: 15000 }); @@ -59283,19 +60779,19 @@ ts() { date -u +%Y-%m-%dT%H:%M:%SZ; } } function isExecutable(path) { try { - statSync(path); + (0, node_fs__rspack_import_1.statSync)(path); } catch { return false; } try { - return (statSync(path).mode & 73) !== 0; + return ((0, node_fs__rspack_import_1.statSync)(path).mode & 73) !== 0; } catch { return false; } } function fileExists(path) { try { - statSync(path); + (0, node_fs__rspack_import_1.statSync)(path); return true; } catch { return false; @@ -59447,12 +60943,12 @@ ts() { date -u +%Y-%m-%dT%H:%M:%SZ; } } function socketStateOf(path) { try { - return statSync(path).isSocket() ? "socket" : "not-a-socket"; + return (0, node_fs__rspack_import_1.statSync)(path).isSocket() ? "socket" : "not-a-socket"; } catch (error) { return error && (error.code === "EACCES" || error.code === "EPERM") ? "permission-denied" : "absent"; } } - function desktopShimStatus1({ env = process.env, home = userHomeDir(env), platform = process.platform, runner = defaultRunner } = {}) { + function desktopShimStatus({ env = process.env, home = userHomeDir(env), platform = process.platform, runner = defaultRunner } = {}) { const paths = defaultPaths({ env, home @@ -59483,7 +60979,7 @@ ts() { date -u +%Y-%m-%dT%H:%M:%SZ; } } const desktopCliPath = platform === "darwin" ? guiCliPath : cliPath; const installed = wrapperPresent && isExecutable(paths.wrapperPath) && bridgePresent; - const socketPath = env.CODEX_APP_SERVER_SOCK || join(paths.codexHome, "app-server-control", "app-server-control.sock"); + const socketPath = env.CODEX_APP_SERVER_SOCK || (0, node_path__rspack_import_3.join)(paths.codexHome, "app-server-control", "app-server-control.sock"); return { action: "status", bridgePath: paths.bridgePath, @@ -59511,6 +61007,9 @@ ts() { date -u +%Y-%m-%dT%H:%M:%SZ; } wrapperPresent }; } + __webpack_require__.d(__webpack_exports__, { + em: ()=>desktopShimStatus + }); }, "./src/core/gateway.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { var node_crypto__rspack_import_0 = __webpack_require__("node:crypto"); From 686ba5fc90e493b59d498d672919d2aed70e29da Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 00:46:27 +0000 Subject: [PATCH 03/26] fix: align ChatGPT Desktop DOM module with exploration results MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tighten cdp-dom selectors against the macOS Desktop probe: exact main window URL filtering, _MainContentSurface thread root, named experimental composer constants, and focus → Input.insertText → submit send order. Co-authored-by: Zack Jackson --- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 144 ++++++++---- artifact/bin/gbot.mjs | 144 ++++++++---- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 144 ++++++++---- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 144 ++++++++---- docs/chatgpt-desktop-cdp.md | 5 +- src/core/chatgpt-desktop/cdp-dom.ts | 205 +++++++++++++----- src/core/chatgpt-desktop/index.ts | 4 + src/core/chatgpt-desktop/relaunch.ts | 6 +- tests/route-unit/chatgpt-desktop.test.ts | 35 +++ 11 files changed, 608 insertions(+), 227 deletions(-) diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 71bf3f8..ac8b627 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"3c68557fc05451064d6ba83e57b2052ab49f0a602a351c0dc03012bb13d8965d"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"7289ed92a861c94d6d5810b57ef6c1d9e874a01583d8c0bbdad4588fb7729c96"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"049698a5689411f659de5081d9277ccd0eb16136869bd3227856289e42e4faaf"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"218892ec3254f387f72606ce06e3d7540af2c5dc14f5d1297cbff9c185ce6de6"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"1e02ce956342af8f78bac0034e21bab1d4f301a85ab52e70ad7e05844f2648e3"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"35e43e80551c4cab38eb0a78eb69722ec954db6990f8e14378828f3e5a9d014e"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"6c285bce6a7c42c31baa50d314b72b16d1da30417377d0db41afa49885f8f002"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"a4fe49753e3db394f8becb015a54c66e6921498df7f47108c72ff74c17f11003"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 90070de..1da6fa5 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"a36888d23691b58e54be76e21b0fecf246832e06dc1328140fb31fa5253e366c","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"9ae489072a2c39c2629f0e3f43d8f6a966b8ad6e25f9be144b5522e835747454","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"f4135bee52844417625ab940db9c733d028452dd10b7fd7d3816e7d33563c445"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"c1e70d400071a7b3e444772cfcf42960d0dfb7b8401588cb8be4d7a489dc012d"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"8b3538068d035d1147916a0f43c8cb24a58e98733c624c18e102eee60184d7ac"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"cd1284db2027910b91c8f0ae7ce1d7c476c7917708018f75f5b7d73088c020de"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"7a2e819d5fc9b29660cf05d5c687165d73af5a0e553460b77e46d53ecad55372"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"fd3c13ab04777bec512e8012d4a3397605719b60887c3d60b24c54c8a2480b57"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"5280b364c75e06e5f00c254f23c21b04144e949590da0c4b02e1c2cbe582aec8"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"994bafdb1ebcd71e4bb997d66d37ad3e4fe202d72258a1408f67b63c152c888f"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"0a39297107040b2a488f6401b7b06d95bc93260318772f1fbc9d2faba2c8510b"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"af1e60e24df9d3256cc5a3cfea6afe9634c6264a8cbb807f1d4b2aaa411115db"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"04900c8c233fe6a34c24bc94fc5c0ed18913a783c2b979ca1fbf4a34afd7903d"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"56a8ea6c9618831131cdf16bb60e1b0e764a4f8c72c9557d926db94f5b7090b8"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"71a6e1498f9b663831526dca85a7390fdfb548f118aa48a8c84c8f9af2815757"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"42283e5dc746ef18b301f317e2556fa17a1af25f4aaa2bf7e77decb2425e436f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"523f8899b9f010ec6dd240e961007fedf1440674dc1995c6551aff2f0b077f54"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"f6586c0913fa64da29f9c1bd4b2ada95aefdd014eea80e802822c332d1e3aba6"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"37a181c673a583a5c0344a10367ee7222cd5aa480f10351b3b337c8c9ef62cb6"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"7dfb0e5cd0117ac38650f83ce257e35f77fe71398b5e5e48c695abbf4d2d7e6c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"7695a3ef40496df91e8d60ba248983c89b1ebdbb3f07e2ec8ffdc2271d33a85d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"976ad8b1c1fc8dae4abe07e2dcbbbb56233f467fd06b1a25d2f4ca056b38ce69"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"327e7c61d5849c82b3bb864286f207ced8979ea546b365b708c7070715501151"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"bb0f72145123dde9bf4438b9f863ddaf4781656972b17f15368c0949145f9c91"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"1ae06583bac9ae9add3371b4b5c77697c6c7492dcd1c0be1a72501876879ae76"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"56454a78aaea180d78e8cd62385ef66261f1748b593aa5165e587d5975205af4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"ee26dc07b4baade26d8154ed7b4cb69c24285f2997f016bbfb8607e728e7e6bb"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"1b4b1c04bf20e035e001db69973f313d154fcc6c9b99fc3abbe4e3a604f5c2d5"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7bfaf1abfe75bc5c2167d9053c76d33ed830a083780d2dc3017492ec3c44799d"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":21751,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"4873f4dc4b1512659a451b4b6400da0008e4760767eb8a333c3fff48966552b5"},{"bytes":1416659,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"3c68557fc05451064d6ba83e57b2052ab49f0a602a351c0dc03012bb13d8965d"},{"bytes":2273620,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"7289ed92a861c94d6d5810b57ef6c1d9e874a01583d8c0bbdad4588fb7729c96"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1331527,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"049698a5689411f659de5081d9277ccd0eb16136869bd3227856289e42e4faaf"},{"bytes":3157291,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"218892ec3254f387f72606ce06e3d7540af2c5dc14f5d1297cbff9c185ce6de6"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281157,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.","exitCode":"result","options":[{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":100,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":100,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start/use a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"a17943a11b9925112cf456b4c5466766a4bd80ec3daeea646798c750ed354516","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend \"cdp\" or \"app-server\".","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"limit":{"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start/use a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"a36888d23691b58e54be76e21b0fecf246832e06dc1328140fb31fa5253e366c","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"2d31e6773eae478ee6e8f92d9a5a177610df2827884a0fd5e727515f1c1a8f5f","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"f4135bee52844417625ab940db9c733d028452dd10b7fd7d3816e7d33563c445"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"0531241b00be5e770bbf7fb6e5f105c8b30e980201b1874cce102c13df027e89"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"8b3538068d035d1147916a0f43c8cb24a58e98733c624c18e102eee60184d7ac"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"cd1284db2027910b91c8f0ae7ce1d7c476c7917708018f75f5b7d73088c020de"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"7a2e819d5fc9b29660cf05d5c687165d73af5a0e553460b77e46d53ecad55372"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"fd3c13ab04777bec512e8012d4a3397605719b60887c3d60b24c54c8a2480b57"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"5280b364c75e06e5f00c254f23c21b04144e949590da0c4b02e1c2cbe582aec8"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"994bafdb1ebcd71e4bb997d66d37ad3e4fe202d72258a1408f67b63c152c888f"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"0a39297107040b2a488f6401b7b06d95bc93260318772f1fbc9d2faba2c8510b"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"af1e60e24df9d3256cc5a3cfea6afe9634c6264a8cbb807f1d4b2aaa411115db"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"20e21bf5a851b23a2e42bdf3dbdec479128f65c38ec0fc1e40c9c7d2bb2a3d27"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"56a8ea6c9618831131cdf16bb60e1b0e764a4f8c72c9557d926db94f5b7090b8"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"71a6e1498f9b663831526dca85a7390fdfb548f118aa48a8c84c8f9af2815757"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"8a08b621b2daf5a8dae93f57876fecccb2c85dac3f87a702c4cb78c5d7fc2123"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"f6586c0913fa64da29f9c1bd4b2ada95aefdd014eea80e802822c332d1e3aba6"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"37a181c673a583a5c0344a10367ee7222cd5aa480f10351b3b337c8c9ef62cb6"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"7dfb0e5cd0117ac38650f83ce257e35f77fe71398b5e5e48c695abbf4d2d7e6c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"7695a3ef40496df91e8d60ba248983c89b1ebdbb3f07e2ec8ffdc2271d33a85d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"976ad8b1c1fc8dae4abe07e2dcbbbb56233f467fd06b1a25d2f4ca056b38ce69"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"327e7c61d5849c82b3bb864286f207ced8979ea546b365b708c7070715501151"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"bb0f72145123dde9bf4438b9f863ddaf4781656972b17f15368c0949145f9c91"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"1ae06583bac9ae9add3371b4b5c77697c6c7492dcd1c0be1a72501876879ae76"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"56454a78aaea180d78e8cd62385ef66261f1748b593aa5165e587d5975205af4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"ee26dc07b4baade26d8154ed7b4cb69c24285f2997f016bbfb8607e728e7e6bb"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"6bfde5e2ba26a087bacbaeaaabd498d7d6d7c82325d100ffc6502a7397f675cb"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7bfaf1abfe75bc5c2167d9053c76d33ed830a083780d2dc3017492ec3c44799d"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":21751,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"7868a99bf8d9ef47407b82501ad52a336cabbb4bc41f2959de28c77649800426"},{"bytes":1419024,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"1e02ce956342af8f78bac0034e21bab1d4f301a85ab52e70ad7e05844f2648e3"},{"bytes":2275985,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"35e43e80551c4cab38eb0a78eb69722ec954db6990f8e14378828f3e5a9d014e"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1333892,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"6c285bce6a7c42c31baa50d314b72b16d1da30417377d0db41afa49885f8f002"},{"bytes":3159656,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"a4fe49753e3db394f8becb015a54c66e6921498df7f47108c72ff74c17f11003"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281157,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.","exitCode":"result","options":[{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":100,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":100,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start/use a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"a17943a11b9925112cf456b4c5466766a4bd80ec3daeea646798c750ed354516","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend \"cdp\" or \"app-server\".","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"limit":{"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start/use a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index 4836946..1ffe7ef 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -11447,6 +11447,12 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { const MAIN_WINDOW_URL = 'app://-/index.html'; + const IGNORED_TARGET_URL_MARKERS = [ + 'initialRoute=%2Favatar-overlay', + 'detached-window.html', + 'chatgpt.com', + 'codex-sandbox' + ]; const ATTR = { threadRow: 'data-app-action-sidebar-thread-row', threadId: 'data-app-action-sidebar-thread-id', @@ -11459,29 +11465,35 @@ var __webpack_modules__ = { timelineScroll: 'data-app-action-timeline-scroll', virtualizedTurn: 'data-virtualized-turn-content' }; + const MAIN_CONTENT_SURFACE_CLASS_PREFIX = '_MainContentSurface'; + const COMPOSER_SELECTORS = [ + 'main [contenteditable="true"]', + 'main textarea', + '[data-app-action-composer] [contenteditable="true"]', + '[data-app-action-composer] textarea', + 'form [contenteditable="true"]', + 'form textarea' + ]; + const SEND_BUTTON_SELECTORS = [ + 'button[data-app-action-send]', + 'button[aria-label="Send"]', + 'button[aria-label="Send message"]', + 'main button[type="submit"]' + ]; const SELECTORS = { threadRow: `[role="button"][${ATTR.threadRow}]`, turn: `[${ATTR.turnKey}]`, userBubble: `[${ATTR.userBubble}]`, timelineScroll: `[${ATTR.timelineScroll}]`, mainSurface: 'main', - composerCandidates: [ - 'main [contenteditable="true"]', - 'main textarea', - '[data-app-action-composer] [contenteditable="true"]', - '[data-app-action-composer] textarea', - 'form [contenteditable="true"]', - 'form textarea' - ], - sendButtonCandidates: [ - 'button[data-app-action-send]', - 'button[aria-label="Send"]', - 'button[aria-label="Send message"]', - 'main button[type="submit"]' - ] + composerCandidates: COMPOSER_SELECTORS, + sendButtonCandidates: SEND_BUTTON_SELECTORS }; function isMainWindowTarget(target) { - return target.type === 'page' && target.url === MAIN_WINDOW_URL; + if (target.type !== 'page') return false; + const url = typeof target.url === 'string' ? target.url : ''; + if (url !== MAIN_WINDOW_URL) return false; + return !IGNORED_TARGET_URL_MARKERS.some((marker)=>url.includes(marker)); } function summarizeTargetInfos(targetInfos) { return targetInfos.filter((t)=>typeof t.targetId === 'string' && typeof t.type === 'string').map((t)=>({ @@ -11516,9 +11528,16 @@ var __webpack_modules__ = { })()`; } const READ_THREAD_EXPRESSION = `(() => { - const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); - const surface = mains.length >= 2 ? mains[1] : (mains[0] || document.body); + const surface = + mains.find((el) => typeof el.className === 'string' && el.className.includes(surfacePrefix)) + || (mains.length >= 2 ? mains[1] : null) + || mains[0] + || document.body; + const scroll = + surface.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}) + || document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); const root = scroll || surface; const collected = new Map(); const statusRe = /^Worked for \\d+s$/i; @@ -11558,16 +11577,24 @@ var __webpack_modules__ = { harvest(); return Array.from(collected.values()); })()`; - function sendMessageExpression(text) { - const composers = JSON.stringify([ - ...SELECTORS.composerCandidates - ]); - const buttons = JSON.stringify([ - ...SELECTORS.sendButtonCandidates - ]); + const FOCUS_COMPOSER_EXPRESSION = `(() => { + const composers = ${JSON.stringify([ + ...COMPOSER_SELECTORS + ])}; + for (const sel of composers) { + const composer = document.querySelector(sel); + if (!composer) continue; + composer.focus(); + return { ok: true, selector: sel, contentEditable: !!composer.isContentEditable }; + } + return { ok: false, error: 'composer-not-found' }; +})()`; + function fillComposerExpression(text) { return `(() => { const text = ${JSON.stringify(text)}; - const composers = ${composers}; + const composers = ${JSON.stringify([ + ...COMPOSER_SELECTORS + ])}; let composer = null; for (const sel of composers) { composer = document.querySelector(sel); @@ -11584,19 +11611,36 @@ var __webpack_modules__ = { } else { return { ok: false, error: 'composer-unsupported' }; } - const buttons = ${buttons}; - let sent = false; - for (const sel of buttons) { - const btn = document.querySelector(sel); - if (btn && !btn.disabled) { btn.click(); sent = true; break; } - } - if (!sent) { - composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true })); - composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', bubbles: true })); - } - return { ok: true, sentVia: sent ? 'button' : 'enter' }; + return { ok: true }; })()`; } + const SUBMIT_COMPOSER_EXPRESSION = `(() => { + const buttons = ${JSON.stringify([ + ...SEND_BUTTON_SELECTORS + ])}; + for (const sel of buttons) { + const btn = document.querySelector(sel); + if (btn && !btn.disabled) { + btn.click(); + return { ok: true, sentVia: 'button', selector: sel }; + } + } + const composers = ${JSON.stringify([ + ...COMPOSER_SELECTORS + ])}; + let composer = null; + for (const sel of composers) { + composer = document.querySelector(sel); + if (composer) break; + } + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); + composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); + return { ok: true, sentVia: 'enter' }; +})()`; + function sendMessageExpression(text) { + return fillComposerExpression(text); + } async function listThreadsFromDom(session, sessionId, { limit = 50 } = {}) { const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { sessionId @@ -11630,21 +11674,39 @@ var __webpack_modules__ = { })); } async function sendMessageInDom(session, sessionId, text) { + const focused = await session.evaluate(FOCUS_COMPOSER_EXPRESSION, { + sessionId + }); + if (!focused?.ok) { + throw new Error('ChatGPT Desktop composer not found (experimental send path)'); + } + let inserted = false; try { await session.send('Input.insertText', { text }, { sessionId }); - } catch {} - const result = await session.evaluate(sendMessageExpression(text), { + inserted = true; + } catch { + inserted = false; + } + if (!inserted) { + const filled = await session.evaluate(fillComposerExpression(text), { + sessionId + }); + if (!filled?.ok) { + throw new Error(filled?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${filled?.error ?? 'fill-failed'}`); + } + } + const submitted = await session.evaluate(SUBMIT_COMPOSER_EXPRESSION, { sessionId }); - if (!result?.ok) { - throw new Error(result?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${result?.error ?? 'unknown'}`); + if (!submitted?.ok) { + throw new Error(`ChatGPT Desktop send submit failed: ${submitted?.error ?? 'unknown'}`); } return { - sentVia: result.sentVia ?? 'unknown' + sentVia: submitted.sentVia ?? (inserted ? 'insertText' : 'dom') }; } __webpack_require__.d(__webpack_exports__, { diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index 5433211..01d22b6 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -9855,6 +9855,12 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { const MAIN_WINDOW_URL = 'app://-/index.html'; + const IGNORED_TARGET_URL_MARKERS = [ + 'initialRoute=%2Favatar-overlay', + 'detached-window.html', + 'chatgpt.com', + 'codex-sandbox' + ]; const ATTR = { threadRow: 'data-app-action-sidebar-thread-row', threadId: 'data-app-action-sidebar-thread-id', @@ -9867,29 +9873,35 @@ var __webpack_modules__ = { timelineScroll: 'data-app-action-timeline-scroll', virtualizedTurn: 'data-virtualized-turn-content' }; + const MAIN_CONTENT_SURFACE_CLASS_PREFIX = '_MainContentSurface'; + const COMPOSER_SELECTORS = [ + 'main [contenteditable="true"]', + 'main textarea', + '[data-app-action-composer] [contenteditable="true"]', + '[data-app-action-composer] textarea', + 'form [contenteditable="true"]', + 'form textarea' + ]; + const SEND_BUTTON_SELECTORS = [ + 'button[data-app-action-send]', + 'button[aria-label="Send"]', + 'button[aria-label="Send message"]', + 'main button[type="submit"]' + ]; const SELECTORS = { threadRow: `[role="button"][${ATTR.threadRow}]`, turn: `[${ATTR.turnKey}]`, userBubble: `[${ATTR.userBubble}]`, timelineScroll: `[${ATTR.timelineScroll}]`, mainSurface: 'main', - composerCandidates: [ - 'main [contenteditable="true"]', - 'main textarea', - '[data-app-action-composer] [contenteditable="true"]', - '[data-app-action-composer] textarea', - 'form [contenteditable="true"]', - 'form textarea' - ], - sendButtonCandidates: [ - 'button[data-app-action-send]', - 'button[aria-label="Send"]', - 'button[aria-label="Send message"]', - 'main button[type="submit"]' - ] + composerCandidates: COMPOSER_SELECTORS, + sendButtonCandidates: SEND_BUTTON_SELECTORS }; function isMainWindowTarget(target) { - return target.type === 'page' && target.url === MAIN_WINDOW_URL; + if (target.type !== 'page') return false; + const url = typeof target.url === 'string' ? target.url : ''; + if (url !== MAIN_WINDOW_URL) return false; + return !IGNORED_TARGET_URL_MARKERS.some((marker)=>url.includes(marker)); } function summarizeTargetInfos(targetInfos) { return targetInfos.filter((t)=>typeof t.targetId === 'string' && typeof t.type === 'string').map((t)=>({ @@ -9924,9 +9936,16 @@ var __webpack_modules__ = { })()`; } const READ_THREAD_EXPRESSION = `(() => { - const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); - const surface = mains.length >= 2 ? mains[1] : (mains[0] || document.body); + const surface = + mains.find((el) => typeof el.className === 'string' && el.className.includes(surfacePrefix)) + || (mains.length >= 2 ? mains[1] : null) + || mains[0] + || document.body; + const scroll = + surface.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}) + || document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); const root = scroll || surface; const collected = new Map(); const statusRe = /^Worked for \\d+s$/i; @@ -9966,16 +9985,24 @@ var __webpack_modules__ = { harvest(); return Array.from(collected.values()); })()`; - function sendMessageExpression(text) { - const composers = JSON.stringify([ - ...SELECTORS.composerCandidates - ]); - const buttons = JSON.stringify([ - ...SELECTORS.sendButtonCandidates - ]); + const FOCUS_COMPOSER_EXPRESSION = `(() => { + const composers = ${JSON.stringify([ + ...COMPOSER_SELECTORS + ])}; + for (const sel of composers) { + const composer = document.querySelector(sel); + if (!composer) continue; + composer.focus(); + return { ok: true, selector: sel, contentEditable: !!composer.isContentEditable }; + } + return { ok: false, error: 'composer-not-found' }; +})()`; + function fillComposerExpression(text) { return `(() => { const text = ${JSON.stringify(text)}; - const composers = ${composers}; + const composers = ${JSON.stringify([ + ...COMPOSER_SELECTORS + ])}; let composer = null; for (const sel of composers) { composer = document.querySelector(sel); @@ -9992,19 +10019,36 @@ var __webpack_modules__ = { } else { return { ok: false, error: 'composer-unsupported' }; } - const buttons = ${buttons}; - let sent = false; - for (const sel of buttons) { - const btn = document.querySelector(sel); - if (btn && !btn.disabled) { btn.click(); sent = true; break; } - } - if (!sent) { - composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true })); - composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', bubbles: true })); - } - return { ok: true, sentVia: sent ? 'button' : 'enter' }; + return { ok: true }; })()`; } + const SUBMIT_COMPOSER_EXPRESSION = `(() => { + const buttons = ${JSON.stringify([ + ...SEND_BUTTON_SELECTORS + ])}; + for (const sel of buttons) { + const btn = document.querySelector(sel); + if (btn && !btn.disabled) { + btn.click(); + return { ok: true, sentVia: 'button', selector: sel }; + } + } + const composers = ${JSON.stringify([ + ...COMPOSER_SELECTORS + ])}; + let composer = null; + for (const sel of composers) { + composer = document.querySelector(sel); + if (composer) break; + } + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); + composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); + return { ok: true, sentVia: 'enter' }; +})()`; + function sendMessageExpression(text) { + return fillComposerExpression(text); + } async function listThreadsFromDom(session, sessionId, { limit = 50 } = {}) { const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { sessionId @@ -10038,21 +10082,39 @@ var __webpack_modules__ = { })); } async function sendMessageInDom(session, sessionId, text) { + const focused = await session.evaluate(FOCUS_COMPOSER_EXPRESSION, { + sessionId + }); + if (!focused?.ok) { + throw new Error('ChatGPT Desktop composer not found (experimental send path)'); + } + let inserted = false; try { await session.send('Input.insertText', { text }, { sessionId }); - } catch {} - const result = await session.evaluate(sendMessageExpression(text), { + inserted = true; + } catch { + inserted = false; + } + if (!inserted) { + const filled = await session.evaluate(fillComposerExpression(text), { + sessionId + }); + if (!filled?.ok) { + throw new Error(filled?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${filled?.error ?? 'fill-failed'}`); + } + } + const submitted = await session.evaluate(SUBMIT_COMPOSER_EXPRESSION, { sessionId }); - if (!result?.ok) { - throw new Error(result?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${result?.error ?? 'unknown'}`); + if (!submitted?.ok) { + throw new Error(`ChatGPT Desktop send submit failed: ${submitted?.error ?? 'unknown'}`); } return { - sentVia: result.sentVia ?? 'unknown' + sentVia: submitted.sentVia ?? (inserted ? 'insertText' : 'dom') }; } __webpack_require__.d(__webpack_exports__, { diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index cb43c34..682250f 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8430,6 +8430,12 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { const MAIN_WINDOW_URL = 'app://-/index.html'; + const IGNORED_TARGET_URL_MARKERS = [ + 'initialRoute=%2Favatar-overlay', + 'detached-window.html', + 'chatgpt.com', + 'codex-sandbox' + ]; const ATTR = { threadRow: 'data-app-action-sidebar-thread-row', threadId: 'data-app-action-sidebar-thread-id', @@ -8442,29 +8448,35 @@ var __webpack_modules__ = { timelineScroll: 'data-app-action-timeline-scroll', virtualizedTurn: 'data-virtualized-turn-content' }; + const MAIN_CONTENT_SURFACE_CLASS_PREFIX = '_MainContentSurface'; + const COMPOSER_SELECTORS = [ + 'main [contenteditable="true"]', + 'main textarea', + '[data-app-action-composer] [contenteditable="true"]', + '[data-app-action-composer] textarea', + 'form [contenteditable="true"]', + 'form textarea' + ]; + const SEND_BUTTON_SELECTORS = [ + 'button[data-app-action-send]', + 'button[aria-label="Send"]', + 'button[aria-label="Send message"]', + 'main button[type="submit"]' + ]; const SELECTORS = { threadRow: `[role="button"][${ATTR.threadRow}]`, turn: `[${ATTR.turnKey}]`, userBubble: `[${ATTR.userBubble}]`, timelineScroll: `[${ATTR.timelineScroll}]`, mainSurface: 'main', - composerCandidates: [ - 'main [contenteditable="true"]', - 'main textarea', - '[data-app-action-composer] [contenteditable="true"]', - '[data-app-action-composer] textarea', - 'form [contenteditable="true"]', - 'form textarea' - ], - sendButtonCandidates: [ - 'button[data-app-action-send]', - 'button[aria-label="Send"]', - 'button[aria-label="Send message"]', - 'main button[type="submit"]' - ] + composerCandidates: COMPOSER_SELECTORS, + sendButtonCandidates: SEND_BUTTON_SELECTORS }; function isMainWindowTarget(target) { - return target.type === 'page' && target.url === MAIN_WINDOW_URL; + if (target.type !== 'page') return false; + const url = typeof target.url === 'string' ? target.url : ''; + if (url !== MAIN_WINDOW_URL) return false; + return !IGNORED_TARGET_URL_MARKERS.some((marker)=>url.includes(marker)); } function summarizeTargetInfos(targetInfos) { return targetInfos.filter((t)=>typeof t.targetId === 'string' && typeof t.type === 'string').map((t)=>({ @@ -8499,9 +8511,16 @@ var __webpack_modules__ = { })()`; } const READ_THREAD_EXPRESSION = `(() => { - const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); - const surface = mains.length >= 2 ? mains[1] : (mains[0] || document.body); + const surface = + mains.find((el) => typeof el.className === 'string' && el.className.includes(surfacePrefix)) + || (mains.length >= 2 ? mains[1] : null) + || mains[0] + || document.body; + const scroll = + surface.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}) + || document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); const root = scroll || surface; const collected = new Map(); const statusRe = /^Worked for \\d+s$/i; @@ -8541,16 +8560,24 @@ var __webpack_modules__ = { harvest(); return Array.from(collected.values()); })()`; - function sendMessageExpression(text) { - const composers = JSON.stringify([ - ...SELECTORS.composerCandidates - ]); - const buttons = JSON.stringify([ - ...SELECTORS.sendButtonCandidates - ]); + const FOCUS_COMPOSER_EXPRESSION = `(() => { + const composers = ${JSON.stringify([ + ...COMPOSER_SELECTORS + ])}; + for (const sel of composers) { + const composer = document.querySelector(sel); + if (!composer) continue; + composer.focus(); + return { ok: true, selector: sel, contentEditable: !!composer.isContentEditable }; + } + return { ok: false, error: 'composer-not-found' }; +})()`; + function fillComposerExpression(text) { return `(() => { const text = ${JSON.stringify(text)}; - const composers = ${composers}; + const composers = ${JSON.stringify([ + ...COMPOSER_SELECTORS + ])}; let composer = null; for (const sel of composers) { composer = document.querySelector(sel); @@ -8567,19 +8594,36 @@ var __webpack_modules__ = { } else { return { ok: false, error: 'composer-unsupported' }; } - const buttons = ${buttons}; - let sent = false; - for (const sel of buttons) { - const btn = document.querySelector(sel); - if (btn && !btn.disabled) { btn.click(); sent = true; break; } - } - if (!sent) { - composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true })); - composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', bubbles: true })); - } - return { ok: true, sentVia: sent ? 'button' : 'enter' }; + return { ok: true }; })()`; } + const SUBMIT_COMPOSER_EXPRESSION = `(() => { + const buttons = ${JSON.stringify([ + ...SEND_BUTTON_SELECTORS + ])}; + for (const sel of buttons) { + const btn = document.querySelector(sel); + if (btn && !btn.disabled) { + btn.click(); + return { ok: true, sentVia: 'button', selector: sel }; + } + } + const composers = ${JSON.stringify([ + ...COMPOSER_SELECTORS + ])}; + let composer = null; + for (const sel of composers) { + composer = document.querySelector(sel); + if (composer) break; + } + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); + composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); + return { ok: true, sentVia: 'enter' }; +})()`; + function sendMessageExpression(text) { + return fillComposerExpression(text); + } async function listThreadsFromDom(session, sessionId, { limit = 50 } = {}) { const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { sessionId @@ -8613,21 +8657,39 @@ var __webpack_modules__ = { })); } async function sendMessageInDom(session, sessionId, text) { + const focused = await session.evaluate(FOCUS_COMPOSER_EXPRESSION, { + sessionId + }); + if (!focused?.ok) { + throw new Error('ChatGPT Desktop composer not found (experimental send path)'); + } + let inserted = false; try { await session.send('Input.insertText', { text }, { sessionId }); - } catch {} - const result = await session.evaluate(sendMessageExpression(text), { + inserted = true; + } catch { + inserted = false; + } + if (!inserted) { + const filled = await session.evaluate(fillComposerExpression(text), { + sessionId + }); + if (!filled?.ok) { + throw new Error(filled?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${filled?.error ?? 'fill-failed'}`); + } + } + const submitted = await session.evaluate(SUBMIT_COMPOSER_EXPRESSION, { sessionId }); - if (!result?.ok) { - throw new Error(result?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${result?.error ?? 'unknown'}`); + if (!submitted?.ok) { + throw new Error(`ChatGPT Desktop send submit failed: ${submitted?.error ?? 'unknown'}`); } return { - sentVia: result.sentVia ?? 'unknown' + sentVia: submitted.sentVia ?? (inserted ? 'insertText' : 'dom') }; } __webpack_require__.d(__webpack_exports__, { diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index 9a76a11..9f916a3 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -6838,6 +6838,12 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { const MAIN_WINDOW_URL = 'app://-/index.html'; + const IGNORED_TARGET_URL_MARKERS = [ + 'initialRoute=%2Favatar-overlay', + 'detached-window.html', + 'chatgpt.com', + 'codex-sandbox' + ]; const ATTR = { threadRow: 'data-app-action-sidebar-thread-row', threadId: 'data-app-action-sidebar-thread-id', @@ -6850,29 +6856,35 @@ var __webpack_modules__ = { timelineScroll: 'data-app-action-timeline-scroll', virtualizedTurn: 'data-virtualized-turn-content' }; + const MAIN_CONTENT_SURFACE_CLASS_PREFIX = '_MainContentSurface'; + const COMPOSER_SELECTORS = [ + 'main [contenteditable="true"]', + 'main textarea', + '[data-app-action-composer] [contenteditable="true"]', + '[data-app-action-composer] textarea', + 'form [contenteditable="true"]', + 'form textarea' + ]; + const SEND_BUTTON_SELECTORS = [ + 'button[data-app-action-send]', + 'button[aria-label="Send"]', + 'button[aria-label="Send message"]', + 'main button[type="submit"]' + ]; const SELECTORS = { threadRow: `[role="button"][${ATTR.threadRow}]`, turn: `[${ATTR.turnKey}]`, userBubble: `[${ATTR.userBubble}]`, timelineScroll: `[${ATTR.timelineScroll}]`, mainSurface: 'main', - composerCandidates: [ - 'main [contenteditable="true"]', - 'main textarea', - '[data-app-action-composer] [contenteditable="true"]', - '[data-app-action-composer] textarea', - 'form [contenteditable="true"]', - 'form textarea' - ], - sendButtonCandidates: [ - 'button[data-app-action-send]', - 'button[aria-label="Send"]', - 'button[aria-label="Send message"]', - 'main button[type="submit"]' - ] + composerCandidates: COMPOSER_SELECTORS, + sendButtonCandidates: SEND_BUTTON_SELECTORS }; function isMainWindowTarget(target) { - return target.type === 'page' && target.url === MAIN_WINDOW_URL; + if (target.type !== 'page') return false; + const url = typeof target.url === 'string' ? target.url : ''; + if (url !== MAIN_WINDOW_URL) return false; + return !IGNORED_TARGET_URL_MARKERS.some((marker)=>url.includes(marker)); } function summarizeTargetInfos(targetInfos) { return targetInfos.filter((t)=>typeof t.targetId === 'string' && typeof t.type === 'string').map((t)=>({ @@ -6907,9 +6919,16 @@ var __webpack_modules__ = { })()`; } const READ_THREAD_EXPRESSION = `(() => { - const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); - const surface = mains.length >= 2 ? mains[1] : (mains[0] || document.body); + const surface = + mains.find((el) => typeof el.className === 'string' && el.className.includes(surfacePrefix)) + || (mains.length >= 2 ? mains[1] : null) + || mains[0] + || document.body; + const scroll = + surface.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}) + || document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); const root = scroll || surface; const collected = new Map(); const statusRe = /^Worked for \\d+s$/i; @@ -6949,16 +6968,24 @@ var __webpack_modules__ = { harvest(); return Array.from(collected.values()); })()`; - function sendMessageExpression(text) { - const composers = JSON.stringify([ - ...SELECTORS.composerCandidates - ]); - const buttons = JSON.stringify([ - ...SELECTORS.sendButtonCandidates - ]); + const FOCUS_COMPOSER_EXPRESSION = `(() => { + const composers = ${JSON.stringify([ + ...COMPOSER_SELECTORS + ])}; + for (const sel of composers) { + const composer = document.querySelector(sel); + if (!composer) continue; + composer.focus(); + return { ok: true, selector: sel, contentEditable: !!composer.isContentEditable }; + } + return { ok: false, error: 'composer-not-found' }; +})()`; + function fillComposerExpression(text) { return `(() => { const text = ${JSON.stringify(text)}; - const composers = ${composers}; + const composers = ${JSON.stringify([ + ...COMPOSER_SELECTORS + ])}; let composer = null; for (const sel of composers) { composer = document.querySelector(sel); @@ -6975,19 +7002,36 @@ var __webpack_modules__ = { } else { return { ok: false, error: 'composer-unsupported' }; } - const buttons = ${buttons}; - let sent = false; - for (const sel of buttons) { - const btn = document.querySelector(sel); - if (btn && !btn.disabled) { btn.click(); sent = true; break; } - } - if (!sent) { - composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true })); - composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', bubbles: true })); - } - return { ok: true, sentVia: sent ? 'button' : 'enter' }; + return { ok: true }; })()`; } + const SUBMIT_COMPOSER_EXPRESSION = `(() => { + const buttons = ${JSON.stringify([ + ...SEND_BUTTON_SELECTORS + ])}; + for (const sel of buttons) { + const btn = document.querySelector(sel); + if (btn && !btn.disabled) { + btn.click(); + return { ok: true, sentVia: 'button', selector: sel }; + } + } + const composers = ${JSON.stringify([ + ...COMPOSER_SELECTORS + ])}; + let composer = null; + for (const sel of composers) { + composer = document.querySelector(sel); + if (composer) break; + } + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); + composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); + return { ok: true, sentVia: 'enter' }; +})()`; + function sendMessageExpression(text) { + return fillComposerExpression(text); + } async function listThreadsFromDom(session, sessionId, { limit = 50 } = {}) { const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { sessionId @@ -7021,21 +7065,39 @@ var __webpack_modules__ = { })); } async function sendMessageInDom(session, sessionId, text) { + const focused = await session.evaluate(FOCUS_COMPOSER_EXPRESSION, { + sessionId + }); + if (!focused?.ok) { + throw new Error('ChatGPT Desktop composer not found (experimental send path)'); + } + let inserted = false; try { await session.send('Input.insertText', { text }, { sessionId }); - } catch {} - const result = await session.evaluate(sendMessageExpression(text), { + inserted = true; + } catch { + inserted = false; + } + if (!inserted) { + const filled = await session.evaluate(fillComposerExpression(text), { + sessionId + }); + if (!filled?.ok) { + throw new Error(filled?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${filled?.error ?? 'fill-failed'}`); + } + } + const submitted = await session.evaluate(SUBMIT_COMPOSER_EXPRESSION, { sessionId }); - if (!result?.ok) { - throw new Error(result?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${result?.error ?? 'unknown'}`); + if (!submitted?.ok) { + throw new Error(`ChatGPT Desktop send submit failed: ${submitted?.error ?? 'unknown'}`); } return { - sentVia: result.sentVia ?? 'unknown' + sentVia: submitted.sentVia ?? (inserted ? 'insertText' : 'dom') }; } __webpack_require__.d(__webpack_exports__, { diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index a01491d..8000f8b 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -9,6 +9,8 @@ stay inside `src/core/chatgpt-desktop/`; MCP tools and CLI commands call the Electron fuses on ChatGPT.app block Node inspect / `RunAsNode`, but they do **not** block Chromium's `--remote-debugging-port`. The port binds to loopback. +Do not depend on `@electron/fuses read` — the framework is renamed +(`Codex Framework.framework`) and that tool fails. ```sh # Helper-printed command (also available from the module): @@ -17,8 +19,7 @@ osascript -e 'tell application "ChatGPT" to quit' \ && open -a /Applications/ChatGPT.app --args --remote-debugging-port=9222 ``` -Bundle id: `com.openai.codex`. Do not depend on `@electron/fuses read` — the -framework is renamed (`Codex Framework.framework`) and that tool fails. +Bundle id: `com.openai.codex` (ChatGPT.app v26.924.22138 / Chrome 154 explored). Override the port with `CHATGPT_DESKTOP_CDP_PORT` or `--port`. diff --git a/src/core/chatgpt-desktop/cdp-dom.ts b/src/core/chatgpt-desktop/cdp-dom.ts index 59a06a6..f64f989 100644 --- a/src/core/chatgpt-desktop/cdp-dom.ts +++ b/src/core/chatgpt-desktop/cdp-dom.ts @@ -4,23 +4,43 @@ * ALL selector and in-page data extraction lives in this module. The adapter * and tools must not invent additional DOM selectors. * - * Evidence (macOS ChatGPT.app / Codex Desktop, Electron, Chrome 154, - * bundle com.openai.codex, v26.924.22138): - * - Main window URL is exactly `app://-/index.html` (no query). + * Evidence (macOS ChatGPT.app, bundle id com.openai.codex, v26.924.22138, + * Electron with renamed `Codex Framework.framework`, Chrome 154): + * - Launch with `--remote-debugging-port` (fuses block Node inspect / RunAsNode + * but not this Chromium flag). Port binds to 127.0.0.1. Do not use + * `@electron/fuses read` (fails on the renamed framework). + * - Prefer CDP `Target.getTargets` (`/json/list` is incomplete + order-unstable). + * - Main window: type `page`, url exactly `app://-/index.html` (no query). + * Ignore avatar-overlay, detached-window, and chatgpt.com / codex-sandbox webviews. * - Sidebar rows: `[role=button][data-app-action-sidebar-thread-row]` with - * `data-app-action-sidebar-thread-{id,title,pinned,selected,kind}`. - * - Thread surface is the second `
` (`_MainContentSurface…`). - * - Turns: `[data-turn-key]`; user bubbles: `[data-user-message-bubble]`. - * - Timeline scroll: `[data-app-action-timeline-scroll]` (virtualized). - * - send/waitForReply composer path is experimental (not fully explored). + * `data-app-action-sidebar-thread-{id,title,pinned,selected,kind}` (ids like + * `local:`; kind seen: local). Rows are not links — click to open; URL + * does not change. + * - Thread surface: second `
` whose class starts with `_MainContentSurface`. + * - Turns: `[data-turn-key]`; user bubbles: `[data-user-message-bubble]`; + * timeline scroll: `[data-app-action-timeline-scroll]` (virtualized via + * `data-virtualized-turn-content`). Scroll top→bottom until turn keys stabilize. + * Voice turns that only show "Worked for Xs" → role `status`. + * - send/waitForReply: not fully explored — experimental composer constants below. */ import type { ChatGptDesktopTarget, ChatGptDesktopThread, ChatGptDesktopTurn } from './types.js'; import type { CdpSession } from './cdp-session.js'; -/** Exact main-window URL; ignore avatar-overlay, detached-window, webviews. */ +/** Exact main-window URL; ignore everything else. */ export const MAIN_WINDOW_URL = 'app://-/index.html'; +/** + * URL fragments that must never be treated as the main ChatGPT window. + * Selection still uses exact `MAIN_WINDOW_URL` equality; these document rejects. + */ +export const IGNORED_TARGET_URL_MARKERS = [ + 'initialRoute=%2Favatar-overlay', + 'detached-window.html', + 'chatgpt.com', + 'codex-sandbox', +] as const; + export const ATTR = { threadRow: 'data-app-action-sidebar-thread-row', threadId: 'data-app-action-sidebar-thread-id', @@ -34,37 +54,50 @@ export const ATTR = { virtualizedTurn: 'data-virtualized-turn-content', } as const; +/** Class-name prefix on the thread's `
` (second main in the document). */ +export const MAIN_CONTENT_SURFACE_CLASS_PREFIX = '_MainContentSurface'; + +/** + * Experimental composer selectors (send/waitForReply not explored on-device yet). + * Prefer a contenteditable / textarea inside the main surface. + */ +export const COMPOSER_SELECTORS = [ + 'main [contenteditable="true"]', + 'main textarea', + '[data-app-action-composer] [contenteditable="true"]', + '[data-app-action-composer] textarea', + 'form [contenteditable="true"]', + 'form textarea', +] as const; + +/** Experimental send-button selectors used after Input.insertText. */ +export const SEND_BUTTON_SELECTORS = [ + 'button[data-app-action-send]', + 'button[aria-label="Send"]', + 'button[aria-label="Send message"]', + 'main button[type="submit"]', +] as const; + export const SELECTORS = { threadRow: `[role="button"][${ATTR.threadRow}]`, turn: `[${ATTR.turnKey}]`, userBubble: `[${ATTR.userBubble}]`, timelineScroll: `[${ATTR.timelineScroll}]`, mainSurface: 'main', - /** - * Experimental composer candidates (send/waitForReply not fully explored). - * Prefer a contenteditable / textarea inside the main surface. - */ - composerCandidates: [ - 'main [contenteditable="true"]', - 'main textarea', - '[data-app-action-composer] [contenteditable="true"]', - '[data-app-action-composer] textarea', - 'form [contenteditable="true"]', - 'form textarea', - ], - sendButtonCandidates: [ - 'button[data-app-action-send]', - 'button[aria-label="Send"]', - 'button[aria-label="Send message"]', - 'main button[type="submit"]', - ], + composerCandidates: COMPOSER_SELECTORS, + sendButtonCandidates: SEND_BUTTON_SELECTORS, } as const; export function isMainWindowTarget(target: { type?: string; url?: string; }): boolean { - return target.type === 'page' && target.url === MAIN_WINDOW_URL; + if (target.type !== 'page') return false; + const url = typeof target.url === 'string' ? target.url : ''; + if (url !== MAIN_WINDOW_URL) return false; + // Exact match already excludes query overlays / detached / webviews; markers + // are a belt-and-suspenders guard if a caller passes a looser URL later. + return !IGNORED_TARGET_URL_MARKERS.some((marker) => url.includes(marker)); } export function summarizeTargetInfos( @@ -119,13 +152,21 @@ export function openThreadExpression(threadId: string): string { /** * Scroll the virtualized timeline and collect turns keyed by data-turn-key. + * Prefer the second `
` whose class starts with `_MainContentSurface`. * User turns contain [data-user-message-bubble]; other turns are assistant/status. * Voice turns that only show "Worked for Xs" become status. */ export const READ_THREAD_EXPRESSION = `(() => { - const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); - const surface = mains.length >= 2 ? mains[1] : (mains[0] || document.body); + const surface = + mains.find((el) => typeof el.className === 'string' && el.className.includes(surfacePrefix)) + || (mains.length >= 2 ? mains[1] : null) + || mains[0] + || document.body; + const scroll = + surface.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}) + || document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); const root = scroll || surface; const collected = new Map(); const statusRe = /^Worked for \\d+s$/i; @@ -166,13 +207,23 @@ export const READ_THREAD_EXPRESSION = `(() => { return Array.from(collected.values()); })()`; -/** Experimental: insert text into the composer and submit (Enter / send button). */ -export function sendMessageExpression(text: string): string { - const composers = JSON.stringify([...SELECTORS.composerCandidates]); - const buttons = JSON.stringify([...SELECTORS.sendButtonCandidates]); +/** Experimental: focus the first matching composer; returns whether it was found. */ +export const FOCUS_COMPOSER_EXPRESSION = `(() => { + const composers = ${JSON.stringify([...COMPOSER_SELECTORS])}; + for (const sel of composers) { + const composer = document.querySelector(sel); + if (!composer) continue; + composer.focus(); + return { ok: true, selector: sel, contentEditable: !!composer.isContentEditable }; + } + return { ok: false, error: 'composer-not-found' }; +})()`; + +/** Experimental: fill composer via DOM when Input.insertText is unavailable. */ +export function fillComposerExpression(text: string): string { return `(() => { const text = ${JSON.stringify(text)}; - const composers = ${composers}; + const composers = ${JSON.stringify([...COMPOSER_SELECTORS])}; let composer = null; for (const sel of composers) { composer = document.querySelector(sel); @@ -189,20 +240,37 @@ export function sendMessageExpression(text: string): string { } else { return { ok: false, error: 'composer-unsupported' }; } - const buttons = ${buttons}; - let sent = false; - for (const sel of buttons) { - const btn = document.querySelector(sel); - if (btn && !btn.disabled) { btn.click(); sent = true; break; } - } - if (!sent) { - composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true })); - composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', bubbles: true })); - } - return { ok: true, sentVia: sent ? 'button' : 'enter' }; + return { ok: true }; })()`; } +/** Experimental: click send or press Enter on the focused composer. */ +export const SUBMIT_COMPOSER_EXPRESSION = `(() => { + const buttons = ${JSON.stringify([...SEND_BUTTON_SELECTORS])}; + for (const sel of buttons) { + const btn = document.querySelector(sel); + if (btn && !btn.disabled) { + btn.click(); + return { ok: true, sentVia: 'button', selector: sel }; + } + } + const composers = ${JSON.stringify([...COMPOSER_SELECTORS])}; + let composer = null; + for (const sel of composers) { + composer = document.querySelector(sel); + if (composer) break; + } + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); + composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); + return { ok: true, sentVia: 'enter' }; +})()`; + +/** @deprecated Prefer FOCUS + Input.insertText + SUBMIT; kept for tests/callers. */ +export function sendMessageExpression(text: string): string { + return fillComposerExpression(text); +} + export async function listThreadsFromDom( session: CdpSession, sessionId: string, @@ -249,27 +317,50 @@ export async function readTurnsFromDom( })); } +/** + * Experimental send: focus composer → CDP Input.insertText → submit + * (send button or Enter). Falls back to DOM fill when insertText fails. + */ export async function sendMessageInDom( session: CdpSession, sessionId: string, text: string, ): Promise<{ sentVia: string }> { - // Prefer CDP Input.insertText when focused; fall back to DOM script. + const focused = await session.evaluate<{ ok: boolean; error?: string }>( + FOCUS_COMPOSER_EXPRESSION, + { sessionId }, + ); + if (!focused?.ok) { + throw new Error('ChatGPT Desktop composer not found (experimental send path)'); + } + + let inserted = false; try { await session.send('Input.insertText', { text }, { sessionId }); + inserted = true; } catch { - // Composer may not be focused yet; the evaluate path focuses + fills. + inserted = false; + } + if (!inserted) { + const filled = await session.evaluate<{ ok: boolean; error?: string }>( + fillComposerExpression(text), + { sessionId }, + ); + if (!filled?.ok) { + throw new Error( + filled?.error === 'composer-not-found' + ? 'ChatGPT Desktop composer not found (experimental send path)' + : `ChatGPT Desktop send failed: ${filled?.error ?? 'fill-failed'}`, + ); + } } - const result = await session.evaluate<{ ok: boolean; error?: string; sentVia?: string }>( - sendMessageExpression(text), + + const submitted = await session.evaluate<{ ok: boolean; sentVia?: string; error?: string }>( + SUBMIT_COMPOSER_EXPRESSION, { sessionId }, ); - if (!result?.ok) { - throw new Error( - result?.error === 'composer-not-found' - ? 'ChatGPT Desktop composer not found (experimental send path)' - : `ChatGPT Desktop send failed: ${result?.error ?? 'unknown'}`, - ); + if (!submitted?.ok) { + throw new Error(`ChatGPT Desktop send submit failed: ${submitted?.error ?? 'unknown'}`); } - return { sentVia: result.sentVia ?? 'unknown' }; + return { sentVia: submitted.sentVia ?? (inserted ? 'insertText' : 'dom') }; } diff --git a/src/core/chatgpt-desktop/index.ts b/src/core/chatgpt-desktop/index.ts index 30fc08b..406e851 100644 --- a/src/core/chatgpt-desktop/index.ts +++ b/src/core/chatgpt-desktop/index.ts @@ -2,8 +2,12 @@ export type { ChatGptDesktopAdapter } from './adapter.js'; export { CdpChatGptDesktopAdapter } from './cdp-adapter.js'; export { ATTR, + COMPOSER_SELECTORS, + IGNORED_TARGET_URL_MARKERS, + MAIN_CONTENT_SURFACE_CLASS_PREFIX, MAIN_WINDOW_URL, SELECTORS, + SEND_BUTTON_SELECTORS, isMainWindowTarget, pickMainWindowTarget, summarizeTargetInfos, diff --git a/src/core/chatgpt-desktop/relaunch.ts b/src/core/chatgpt-desktop/relaunch.ts index 00b7e24..fda4fbe 100644 --- a/src/core/chatgpt-desktop/relaunch.ts +++ b/src/core/chatgpt-desktop/relaunch.ts @@ -7,8 +7,10 @@ export const CHATGPT_BUNDLE_ID = 'com.openai.codex'; /** * Shell command that quits ChatGPT Desktop and relaunches it with a local - * Chromium `--remote-debugging-port`. The Electron fuses block Node inspect / + * Chromium `--remote-debugging-port`. Electron fuses block Node inspect / * RunAsNode, but not this Chromium flag. The port binds to 127.0.0.1 only. + * Do not depend on `@electron/fuses read` — the framework is renamed + * (`Codex Framework.framework`) and that tool fails. */ export function chatgptDesktopRelaunchCommand({ port = DEFAULT_CDP_PORT, @@ -18,7 +20,7 @@ export function chatgptDesktopRelaunchCommand({ appPath?: string; } = {}): string { const resolved = resolveCdpPort(process.env, port); - // Prefer `open -a` with --args so the debug port is on Chromium's argv. + // Match explored launch: quit, then `open -a … --args --remote-debugging-port=N`. return [ `osascript -e 'tell application "ChatGPT" to quit'`, `open -a ${shellQuote(appPath)} --args --remote-debugging-port=${resolved}`, diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index c247e93..35cd0de 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -114,6 +114,41 @@ describe('chatgpt-desktop loopback + relaunch helpers', () => { expect(chatgptDesktopRelaunchCommand({ port: 9333 })).toContain( '--remote-debugging-port=9333', ); + expect(chatgptDesktopRelaunchCommand({ port: 9222 })).toContain( + 'open -a /Applications/ChatGPT.app --args --remote-debugging-port=9222', + ); + }); + + it('selects only the exact main window URL and ignores overlays/webviews', async () => { + const { + IGNORED_TARGET_URL_MARKERS, + MAIN_WINDOW_URL, + COMPOSER_SELECTORS, + SEND_BUTTON_SELECTORS, + isMainWindowTarget, + pickMainWindowTarget, + summarizeTargetInfos, + } = await import('../../src/core/chatgpt-desktop/cdp-dom.js'); + + expect(isMainWindowTarget({ type: 'page', url: MAIN_WINDOW_URL })).toBe(true); + expect( + isMainWindowTarget({ + type: 'page', + url: 'app://-/index.html?initialRoute=%2Favatar-overlay', + }), + ).toBe(false); + expect(isMainWindowTarget({ type: 'page', url: 'app://-/detached-window.html' })).toBe(false); + expect(isMainWindowTarget({ type: 'page', url: 'https://chatgpt.com/pricing' })).toBe(false); + expect(IGNORED_TARGET_URL_MARKERS.length).toBeGreaterThan(0); + expect(COMPOSER_SELECTORS[0]).toContain('contenteditable'); + expect(SEND_BUTTON_SELECTORS.length).toBeGreaterThan(0); + + const targets = summarizeTargetInfos([ + { targetId: 'overlay', type: 'page', url: 'app://-/index.html?initialRoute=%2Favatar-overlay' }, + { targetId: 'main', type: 'page', title: 'ChatGPT', url: MAIN_WINDOW_URL }, + { targetId: 'web', type: 'page', url: 'https://chatgpt.com/pricing' }, + ]); + expect(pickMainWindowTarget(targets)?.targetId).toBe('main'); }); }); From 6155184f201af7812139c7449791ded1d6ce4b9d Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 00:48:29 +0000 Subject: [PATCH 04/26] test: cover CDP-first facade with app-server backend fallback Prove chatgpt_desktop_* prefer CDP, reuse codex-bridge when CDP is unreachable, and tag results with backend cdp|app-server. NotImplemented DOM gaps do not trigger fallback. Co-authored-by: Zack Jackson --- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 24 ++- artifact/bin/gbot.mjs | 24 ++- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 24 ++- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 24 ++- docs/chatgpt-desktop-cdp.md | 7 +- src/core/chatgpt-desktop/facade.ts | 46 ++++-- src/core/chatgpt-desktop/index.ts | 1 + tests/route-unit/chatgpt-desktop.test.ts | 138 ++++++++++++++++++ 10 files changed, 250 insertions(+), 42 deletions(-) diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index ac8b627..0e499cb 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"1e02ce956342af8f78bac0034e21bab1d4f301a85ab52e70ad7e05844f2648e3"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"35e43e80551c4cab38eb0a78eb69722ec954db6990f8e14378828f3e5a9d014e"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"6c285bce6a7c42c31baa50d314b72b16d1da30417377d0db41afa49885f8f002"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"a4fe49753e3db394f8becb015a54c66e6921498df7f47108c72ff74c17f11003"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"08b47068d7470c44ad8b35f8d84dd2440f6fcc00674139231e2431e7c5d70bcc"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"90755468ff34ba30d11ec8481b8a60b499f8d8b531d0a2d3b6cd1d8565b1cd68"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"0020602bdb7f33ddda058b4d1424edd9a3dcf2ef9d69419e0f7af3f37ae4864b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"f661f7a8ce1f2856f5ab7b3a36043e514704e6924d80f4746ad3222a08f6bb08"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 1da6fa5..e7b6077 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"a36888d23691b58e54be76e21b0fecf246832e06dc1328140fb31fa5253e366c","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"2d31e6773eae478ee6e8f92d9a5a177610df2827884a0fd5e727515f1c1a8f5f","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"f4135bee52844417625ab940db9c733d028452dd10b7fd7d3816e7d33563c445"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"0531241b00be5e770bbf7fb6e5f105c8b30e980201b1874cce102c13df027e89"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"8b3538068d035d1147916a0f43c8cb24a58e98733c624c18e102eee60184d7ac"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"cd1284db2027910b91c8f0ae7ce1d7c476c7917708018f75f5b7d73088c020de"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"7a2e819d5fc9b29660cf05d5c687165d73af5a0e553460b77e46d53ecad55372"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"fd3c13ab04777bec512e8012d4a3397605719b60887c3d60b24c54c8a2480b57"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"5280b364c75e06e5f00c254f23c21b04144e949590da0c4b02e1c2cbe582aec8"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"994bafdb1ebcd71e4bb997d66d37ad3e4fe202d72258a1408f67b63c152c888f"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"0a39297107040b2a488f6401b7b06d95bc93260318772f1fbc9d2faba2c8510b"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"af1e60e24df9d3256cc5a3cfea6afe9634c6264a8cbb807f1d4b2aaa411115db"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"20e21bf5a851b23a2e42bdf3dbdec479128f65c38ec0fc1e40c9c7d2bb2a3d27"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"56a8ea6c9618831131cdf16bb60e1b0e764a4f8c72c9557d926db94f5b7090b8"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"71a6e1498f9b663831526dca85a7390fdfb548f118aa48a8c84c8f9af2815757"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"8a08b621b2daf5a8dae93f57876fecccb2c85dac3f87a702c4cb78c5d7fc2123"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"f6586c0913fa64da29f9c1bd4b2ada95aefdd014eea80e802822c332d1e3aba6"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"37a181c673a583a5c0344a10367ee7222cd5aa480f10351b3b337c8c9ef62cb6"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"7dfb0e5cd0117ac38650f83ce257e35f77fe71398b5e5e48c695abbf4d2d7e6c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"7695a3ef40496df91e8d60ba248983c89b1ebdbb3f07e2ec8ffdc2271d33a85d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"976ad8b1c1fc8dae4abe07e2dcbbbb56233f467fd06b1a25d2f4ca056b38ce69"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"327e7c61d5849c82b3bb864286f207ced8979ea546b365b708c7070715501151"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"bb0f72145123dde9bf4438b9f863ddaf4781656972b17f15368c0949145f9c91"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"1ae06583bac9ae9add3371b4b5c77697c6c7492dcd1c0be1a72501876879ae76"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"56454a78aaea180d78e8cd62385ef66261f1748b593aa5165e587d5975205af4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"ee26dc07b4baade26d8154ed7b4cb69c24285f2997f016bbfb8607e728e7e6bb"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"6bfde5e2ba26a087bacbaeaaabd498d7d6d7c82325d100ffc6502a7397f675cb"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7bfaf1abfe75bc5c2167d9053c76d33ed830a083780d2dc3017492ec3c44799d"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":21751,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"7868a99bf8d9ef47407b82501ad52a336cabbb4bc41f2959de28c77649800426"},{"bytes":1419024,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"1e02ce956342af8f78bac0034e21bab1d4f301a85ab52e70ad7e05844f2648e3"},{"bytes":2275985,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"35e43e80551c4cab38eb0a78eb69722ec954db6990f8e14378828f3e5a9d014e"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1333892,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"6c285bce6a7c42c31baa50d314b72b16d1da30417377d0db41afa49885f8f002"},{"bytes":3159656,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"a4fe49753e3db394f8becb015a54c66e6921498df7f47108c72ff74c17f11003"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281157,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.","exitCode":"result","options":[{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":100,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":100,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start/use a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"a17943a11b9925112cf456b4c5466766a4bd80ec3daeea646798c750ed354516","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend \"cdp\" or \"app-server\".","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"limit":{"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start/use a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"a36888d23691b58e54be76e21b0fecf246832e06dc1328140fb31fa5253e366c","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"22e4e18e64995f3c7e3acf25c9138344ff6c6b01f0fa6d36dabfaa1d65acc839","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"f4135bee52844417625ab940db9c733d028452dd10b7fd7d3816e7d33563c445"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"74f9a2a23bf23c9e496fe7fa893f1fad6cf018e35dc0ada37cc84c1cdef5644f"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"8b3538068d035d1147916a0f43c8cb24a58e98733c624c18e102eee60184d7ac"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"cd1284db2027910b91c8f0ae7ce1d7c476c7917708018f75f5b7d73088c020de"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"7a2e819d5fc9b29660cf05d5c687165d73af5a0e553460b77e46d53ecad55372"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"fd3c13ab04777bec512e8012d4a3397605719b60887c3d60b24c54c8a2480b57"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"5280b364c75e06e5f00c254f23c21b04144e949590da0c4b02e1c2cbe582aec8"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"994bafdb1ebcd71e4bb997d66d37ad3e4fe202d72258a1408f67b63c152c888f"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"0a39297107040b2a488f6401b7b06d95bc93260318772f1fbc9d2faba2c8510b"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"af1e60e24df9d3256cc5a3cfea6afe9634c6264a8cbb807f1d4b2aaa411115db"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"20e21bf5a851b23a2e42bdf3dbdec479128f65c38ec0fc1e40c9c7d2bb2a3d27"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"56a8ea6c9618831131cdf16bb60e1b0e764a4f8c72c9557d926db94f5b7090b8"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"892e6afecb66d26ba228e35c95694563a206c29d11fbb36e24889a2668e98780"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"da1e1d85f8673af3bcdbf3f23425d75d3db7a5c6080c26bc9e902b643720316f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"f6586c0913fa64da29f9c1bd4b2ada95aefdd014eea80e802822c332d1e3aba6"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"37a181c673a583a5c0344a10367ee7222cd5aa480f10351b3b337c8c9ef62cb6"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"7dfb0e5cd0117ac38650f83ce257e35f77fe71398b5e5e48c695abbf4d2d7e6c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"7695a3ef40496df91e8d60ba248983c89b1ebdbb3f07e2ec8ffdc2271d33a85d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"976ad8b1c1fc8dae4abe07e2dcbbbb56233f467fd06b1a25d2f4ca056b38ce69"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"327e7c61d5849c82b3bb864286f207ced8979ea546b365b708c7070715501151"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"bb0f72145123dde9bf4438b9f863ddaf4781656972b17f15368c0949145f9c91"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"1ae06583bac9ae9add3371b4b5c77697c6c7492dcd1c0be1a72501876879ae76"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"56454a78aaea180d78e8cd62385ef66261f1748b593aa5165e587d5975205af4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"ee26dc07b4baade26d8154ed7b4cb69c24285f2997f016bbfb8607e728e7e6bb"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"cb29cb40fdae0929649123705142adb75c108e689ffa90901737071d7e0d5bbc"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7bfaf1abfe75bc5c2167d9053c76d33ed830a083780d2dc3017492ec3c44799d"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":21751,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"4c107ff9b3c621f9555e173ed827a1d69421fb55348579bf748738afdf8b1202"},{"bytes":1419460,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"08b47068d7470c44ad8b35f8d84dd2440f6fcc00674139231e2431e7c5d70bcc"},{"bytes":2276421,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"90755468ff34ba30d11ec8481b8a60b499f8d8b531d0a2d3b6cd1d8565b1cd68"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1334328,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"0020602bdb7f33ddda058b4d1424edd9a3dcf2ef9d69419e0f7af3f37ae4864b"},{"bytes":3160092,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"f661f7a8ce1f2856f5ab7b3a36043e514704e6924d80f4746ad3222a08f6bb08"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281157,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.","exitCode":"result","options":[{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":100,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":100,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start/use a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"a17943a11b9925112cf456b4c5466766a4bd80ec3daeea646798c750ed354516","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend \"cdp\" or \"app-server\".","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"limit":{"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start/use a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index 1ffe7ef..2bf21c9 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -11914,13 +11914,23 @@ var __webpack_modules__ = { var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + const defaultFallbacks = { + listThreads: _app_server_fallback_js__rspack_import_1.OI, + readThread: _app_server_fallback_js__rspack_import_1.Jf, + sendMessage: _app_server_fallback_js__rspack_import_1.Ab, + waitForReply: _app_server_fallback_js__rspack_import_1.bk, + openThread: _app_server_fallback_js__rspack_import_1.zu, + statusProbe: _app_server_fallback_js__rspack_import_1.dM + }; class ChatGptDesktopFacade { #cdp; #port; #cdpConnected = false; - constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)()){ + #fallbacks; + constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)(), fallbacks = defaultFallbacks){ this.#cdp = cdp; this.#port = port; + this.#fallbacks = fallbacks; } async connect({ port }) { this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); @@ -11944,7 +11954,7 @@ var __webpack_modules__ = { return await this.#cdp.listThreads(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.OI)(options); + return this.#fallbacks.listThreads(options); } } async readThread(options) { @@ -11953,7 +11963,7 @@ var __webpack_modules__ = { return await this.#cdp.readThread(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.Jf)(options); + return this.#fallbacks.readThread(options); } } async sendMessage(options) { @@ -11962,7 +11972,7 @@ var __webpack_modules__ = { return await this.#cdp.sendMessage(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.Ab)(options); + return this.#fallbacks.sendMessage(options); } } async waitForReply(options) { @@ -11971,7 +11981,7 @@ var __webpack_modules__ = { return await this.#cdp.waitForReply(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.bk)(options); + return this.#fallbacks.waitForReply(options); } } async openThread(threadId) { @@ -11980,14 +11990,14 @@ var __webpack_modules__ = { return await this.#cdp.openThread(threadId); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.zu)(threadId); + return this.#fallbacks.openThread(threadId); } } async status() { const cdpStatus = await this.#cdp.status(); let appServerFallback; try { - appServerFallback = await (0, _app_server_fallback_js__rspack_import_1.dM)(); + appServerFallback = await this.#fallbacks.statusProbe(); } catch { appServerFallback = { reachable: false diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index 01d22b6..a3a2a42 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -10322,13 +10322,23 @@ var __webpack_modules__ = { var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + const defaultFallbacks = { + listThreads: _app_server_fallback_js__rspack_import_1.OI, + readThread: _app_server_fallback_js__rspack_import_1.Jf, + sendMessage: _app_server_fallback_js__rspack_import_1.Ab, + waitForReply: _app_server_fallback_js__rspack_import_1.bk, + openThread: _app_server_fallback_js__rspack_import_1.zu, + statusProbe: _app_server_fallback_js__rspack_import_1.dM + }; class ChatGptDesktopFacade { #cdp; #port; #cdpConnected = false; - constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)()){ + #fallbacks; + constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)(), fallbacks = defaultFallbacks){ this.#cdp = cdp; this.#port = port; + this.#fallbacks = fallbacks; } async connect({ port }) { this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); @@ -10352,7 +10362,7 @@ var __webpack_modules__ = { return await this.#cdp.listThreads(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.OI)(options); + return this.#fallbacks.listThreads(options); } } async readThread(options) { @@ -10361,7 +10371,7 @@ var __webpack_modules__ = { return await this.#cdp.readThread(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.Jf)(options); + return this.#fallbacks.readThread(options); } } async sendMessage(options) { @@ -10370,7 +10380,7 @@ var __webpack_modules__ = { return await this.#cdp.sendMessage(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.Ab)(options); + return this.#fallbacks.sendMessage(options); } } async waitForReply(options) { @@ -10379,7 +10389,7 @@ var __webpack_modules__ = { return await this.#cdp.waitForReply(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.bk)(options); + return this.#fallbacks.waitForReply(options); } } async openThread(threadId) { @@ -10388,14 +10398,14 @@ var __webpack_modules__ = { return await this.#cdp.openThread(threadId); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.zu)(threadId); + return this.#fallbacks.openThread(threadId); } } async status() { const cdpStatus = await this.#cdp.status(); let appServerFallback; try { - appServerFallback = await (0, _app_server_fallback_js__rspack_import_1.dM)(); + appServerFallback = await this.#fallbacks.statusProbe(); } catch { appServerFallback = { reachable: false diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index 682250f..fcf9a25 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8897,13 +8897,23 @@ var __webpack_modules__ = { var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + const defaultFallbacks = { + listThreads: _app_server_fallback_js__rspack_import_1.OI, + readThread: _app_server_fallback_js__rspack_import_1.Jf, + sendMessage: _app_server_fallback_js__rspack_import_1.Ab, + waitForReply: _app_server_fallback_js__rspack_import_1.bk, + openThread: _app_server_fallback_js__rspack_import_1.zu, + statusProbe: _app_server_fallback_js__rspack_import_1.dM + }; class ChatGptDesktopFacade { #cdp; #port; #cdpConnected = false; - constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)()){ + #fallbacks; + constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)(), fallbacks = defaultFallbacks){ this.#cdp = cdp; this.#port = port; + this.#fallbacks = fallbacks; } async connect({ port }) { this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); @@ -8927,7 +8937,7 @@ var __webpack_modules__ = { return await this.#cdp.listThreads(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.OI)(options); + return this.#fallbacks.listThreads(options); } } async readThread(options) { @@ -8936,7 +8946,7 @@ var __webpack_modules__ = { return await this.#cdp.readThread(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.Jf)(options); + return this.#fallbacks.readThread(options); } } async sendMessage(options) { @@ -8945,7 +8955,7 @@ var __webpack_modules__ = { return await this.#cdp.sendMessage(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.Ab)(options); + return this.#fallbacks.sendMessage(options); } } async waitForReply(options) { @@ -8954,7 +8964,7 @@ var __webpack_modules__ = { return await this.#cdp.waitForReply(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.bk)(options); + return this.#fallbacks.waitForReply(options); } } async openThread(threadId) { @@ -8963,14 +8973,14 @@ var __webpack_modules__ = { return await this.#cdp.openThread(threadId); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.zu)(threadId); + return this.#fallbacks.openThread(threadId); } } async status() { const cdpStatus = await this.#cdp.status(); let appServerFallback; try { - appServerFallback = await (0, _app_server_fallback_js__rspack_import_1.dM)(); + appServerFallback = await this.#fallbacks.statusProbe(); } catch { appServerFallback = { reachable: false diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index 9f916a3..d9f36bc 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -7305,13 +7305,23 @@ var __webpack_modules__ = { var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + const defaultFallbacks = { + listThreads: _app_server_fallback_js__rspack_import_1.OI, + readThread: _app_server_fallback_js__rspack_import_1.Jf, + sendMessage: _app_server_fallback_js__rspack_import_1.Ab, + waitForReply: _app_server_fallback_js__rspack_import_1.bk, + openThread: _app_server_fallback_js__rspack_import_1.zu, + statusProbe: _app_server_fallback_js__rspack_import_1.dM + }; class ChatGptDesktopFacade { #cdp; #port; #cdpConnected = false; - constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)()){ + #fallbacks; + constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)(), fallbacks = defaultFallbacks){ this.#cdp = cdp; this.#port = port; + this.#fallbacks = fallbacks; } async connect({ port }) { this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); @@ -7335,7 +7345,7 @@ var __webpack_modules__ = { return await this.#cdp.listThreads(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.OI)(options); + return this.#fallbacks.listThreads(options); } } async readThread(options) { @@ -7344,7 +7354,7 @@ var __webpack_modules__ = { return await this.#cdp.readThread(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.Jf)(options); + return this.#fallbacks.readThread(options); } } async sendMessage(options) { @@ -7353,7 +7363,7 @@ var __webpack_modules__ = { return await this.#cdp.sendMessage(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.Ab)(options); + return this.#fallbacks.sendMessage(options); } } async waitForReply(options) { @@ -7362,7 +7372,7 @@ var __webpack_modules__ = { return await this.#cdp.waitForReply(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.bk)(options); + return this.#fallbacks.waitForReply(options); } } async openThread(threadId) { @@ -7371,14 +7381,14 @@ var __webpack_modules__ = { return await this.#cdp.openThread(threadId); } catch (error) { if (!isCdpFailure(error)) throw error; - return (0, _app_server_fallback_js__rspack_import_1.zu)(threadId); + return this.#fallbacks.openThread(threadId); } } async status() { const cdpStatus = await this.#cdp.status(); let appServerFallback; try { - appServerFallback = await (0, _app_server_fallback_js__rspack_import_1.dM)(); + appServerFallback = await this.#fallbacks.statusProbe(); } catch { appServerFallback = { reachable: false diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index 8000f8b..9dd224e 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -60,6 +60,9 @@ bubbles, experimental composer candidates). Do not add selectors elsewhere. ## Fallback -When CDP is unreachable, list/read/send/wait/open fall back to the existing -Codex app-server client in `codex-bridge.js` (no duplicated JSON-RPC stack). +CDP is the primary path for `chatgpt_desktop_*` because Desktop can do more +than the Codex app-server. When CDP is unreachable, list/read/send/wait/open +reuse the existing client in `codex-bridge.js` (`listCodexThreads`, +`openCodexSession`, `sendToCodexThread`, `codexStatus`) — no duplicated +JSON-RPC stack. Each of those results includes `backend: "cdp" | "app-server"`. Starting a brand-new Desktop thread without a `threadId` still needs CDP. diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index b451a9e..b07296e 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -20,19 +20,45 @@ import type { WaitForReplyResult, } from './types.js'; +/** Optional overrides so tests can prove CDP→app-server fallback without a live daemon. */ +export type ChatGptDesktopFallbacks = { + listThreads: typeof appServerListThreads; + readThread: typeof appServerReadThread; + sendMessage: typeof appServerSendMessage; + waitForReply: typeof appServerWaitForReply; + openThread: typeof appServerOpenThread; + statusProbe: typeof appServerStatusProbe; +}; + +const defaultFallbacks: ChatGptDesktopFallbacks = { + listThreads: appServerListThreads, + readThread: appServerReadThread, + sendMessage: appServerSendMessage, + waitForReply: appServerWaitForReply, + openThread: appServerOpenThread, + statusProbe: appServerStatusProbe, +}; + /** - * Prefer CDP for ChatGPT Desktop; fall back to the existing Codex app-server - * client when CDP is unreachable for operations that app-server can serve. - * Every result reports `backend: "cdp" | "app-server"`. + * Prefer CDP for ChatGPT Desktop (Desktop can do more than app-server). + * When CDP is unreachable, reuse the existing Codex app-server client for + * operations it already serves — never duplicate that JSON-RPC stack. + * Every list/read/send/wait/open result reports `backend: "cdp" | "app-server"`. */ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { #cdp: ChatGptDesktopAdapter; #port: number; #cdpConnected = false; + #fallbacks: ChatGptDesktopFallbacks; - constructor(cdp: ChatGptDesktopAdapter = new CdpChatGptDesktopAdapter(), port = resolveCdpPort()) { + constructor( + cdp: ChatGptDesktopAdapter = new CdpChatGptDesktopAdapter(), + port = resolveCdpPort(), + fallbacks: ChatGptDesktopFallbacks = defaultFallbacks, + ) { this.#cdp = cdp; this.#port = port; + this.#fallbacks = fallbacks; } async connect({ port }: { port: number }): Promise { @@ -57,7 +83,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { return await this.#cdp.listThreads(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return appServerListThreads(options); + return this.#fallbacks.listThreads(options); } } @@ -67,7 +93,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { return await this.#cdp.readThread(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return appServerReadThread(options); + return this.#fallbacks.readThread(options); } } @@ -77,7 +103,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { return await this.#cdp.sendMessage(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return appServerSendMessage(options); + return this.#fallbacks.sendMessage(options); } } @@ -90,7 +116,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { return await this.#cdp.waitForReply(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return appServerWaitForReply(options); + return this.#fallbacks.waitForReply(options); } } @@ -100,7 +126,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { return await this.#cdp.openThread(threadId); } catch (error) { if (!isCdpFailure(error)) throw error; - return appServerOpenThread(threadId); + return this.#fallbacks.openThread(threadId); } } @@ -108,7 +134,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { const cdpStatus = await this.#cdp.status(); let appServerFallback: ChatGptDesktopStatus['appServerFallback']; try { - appServerFallback = await appServerStatusProbe(); + appServerFallback = await this.#fallbacks.statusProbe(); } catch { appServerFallback = { reachable: false }; } diff --git a/src/core/chatgpt-desktop/index.ts b/src/core/chatgpt-desktop/index.ts index 406e851..58368b3 100644 --- a/src/core/chatgpt-desktop/index.ts +++ b/src/core/chatgpt-desktop/index.ts @@ -23,6 +23,7 @@ export { getChatGptDesktopAdapter, setChatGptDesktopAdapterForTests, } from './facade.js'; +export type { ChatGptDesktopFallbacks } from './facade.js'; export { CDP_LOOPBACK_HOST, DEFAULT_CDP_PORT, diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index 35cd0de..b074d9e 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -7,12 +7,14 @@ import { invokeCli, invokeMcpTool, listMcpSurface } from 'agent-bundle/test'; import type { ChatGptDesktopAdapter } from '../../src/core/chatgpt-desktop/adapter.js'; import { CdpHostRejectedError, + CdpUnreachableError, NotImplementedError, assertLoopbackHostname, chatgptDesktopRelaunchCommand, forceLoopbackWebSocketUrl, setChatGptDesktopAdapterForTests, } from '../../src/core/chatgpt-desktop/index.js'; +import { ChatGptDesktopFacade } from '../../src/core/chatgpt-desktop/facade.js'; const desktopTools = [ 'chatgpt_desktop_list_threads', @@ -302,6 +304,142 @@ describe('chatgpt-desktop CLI', () => { }); }); +describe('chatgpt-desktop CDP→app-server fallback', () => { + it('prefers CDP, then reuses app-server fallbacks with backend tagging', async () => { + const calls: string[] = []; + const unreachable = new CdpUnreachableError('CDP down'); + const cdp = fakeAdapter({ + async connect() { + calls.push('cdp.connect'); + throw unreachable; + }, + async listThreads() { + calls.push('cdp.listThreads'); + throw unreachable; + }, + async readThread() { + calls.push('cdp.readThread'); + throw unreachable; + }, + async sendMessage() { + calls.push('cdp.sendMessage'); + throw unreachable; + }, + async status() { + return { + reachable: false, + port: 9222, + host: '127.0.0.1', + message: 'CDP down', + exitCode: 1, + }; + }, + }); + + const facade = new ChatGptDesktopFacade(cdp, 9222, { + listThreads: async ({ limit = 50 } = {}) => { + calls.push('app-server.listThreads'); + return { + backend: 'app-server', + limit, + threads: [ + { + threadId: 'codex-1', + title: 'from app-server', + pinned: false, + selected: false, + kind: 'codex', + }, + ], + }; + }, + readThread: async ({ threadId, limit = 100 }) => { + calls.push('app-server.readThread'); + return { + threadId, + backend: 'app-server', + limit, + turns: [{ turnKey: 't1', role: 'assistant', text: 'fallback reply' }], + }; + }, + sendMessage: async ({ threadId, text }) => { + calls.push('app-server.sendMessage'); + return { + threadId: threadId ?? 'missing', + backend: 'app-server', + experimental: false, + delivery: 'accepted', + message: text, + }; + }, + waitForReply: async ({ threadId }) => ({ + threadId, + reply: 'fallback reply', + backend: 'app-server', + experimental: false, + delivery: 'replied' as const, + }), + openThread: async (threadId) => ({ threadId, backend: 'app-server' as const }), + statusProbe: async () => ({ reachable: true, mode: 'daemon', socketPath: '/tmp/fake.sock' }), + }); + + const listed = await facade.listThreads({ limit: 5 }); + expect(listed).toMatchObject({ backend: 'app-server', threads: [{ threadId: 'codex-1' }] }); + + const read = await facade.readThread({ threadId: 'codex-1' }); + expect(read).toMatchObject({ backend: 'app-server', turns: [{ text: 'fallback reply' }] }); + + const sent = await facade.sendMessage({ threadId: 'codex-1', text: 'hi' }); + expect(sent).toMatchObject({ backend: 'app-server', delivery: 'accepted' }); + + const status = await facade.status(); + expect(status).toMatchObject({ + reachable: true, + appServerFallback: { reachable: true, mode: 'daemon' }, + message: 'CDP unreachable; Codex app-server fallback is available', + exitCode: 0, + }); + + expect(calls.filter((c) => c.startsWith('app-server'))).toEqual([ + 'app-server.listThreads', + 'app-server.readThread', + 'app-server.sendMessage', + ]); + expect(calls.some((c) => c.startsWith('cdp.'))).toBe(true); + }); + + it('does not fall back for NotImplemented DOM gaps', async () => { + const facade = new ChatGptDesktopFacade( + fakeAdapter({ + async connect() {}, + async listThreads() { + throw new NotImplementedError('listThreads'); + }, + }), + 9222, + { + listThreads: async () => { + throw new Error('app-server should not run'); + }, + readThread: async () => { + throw new Error('unused'); + }, + sendMessage: async () => { + throw new Error('unused'); + }, + waitForReply: async () => { + throw new Error('unused'); + }, + openThread: async () => { + throw new Error('unused'); + }, + statusProbe: async () => ({ reachable: false }), + }, + ); + await expect(facade.listThreads()).rejects.toBeInstanceOf(NotImplementedError); + }); +}); + describe('chatgpt-desktop CDP HTTP status probe', () => { it('reports reachable when /json/version answers on loopback', async () => { const server: Server = createServer((req, res) => { From b0490e5cd678dfeb9a2c02e7f68f9b3f3764d898 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 00:56:43 +0000 Subject: [PATCH 05/26] feat: align ChatGPT Desktop CDP send/wait/read with live DOM Update cdp-dom and the adapter to the verified Desktop behaviors: project new-chat button, composer focus+insertText+Enter, Stop/final-assistant reply detection, conversation-id annotation, Loading task wait, and column-reverse mouseWheel full history reads with limit/full. Co-authored-by: Zack Jackson --- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 718 +++++++++++------ artifact/bin/gbot.mjs | 757 ++++++++++++------ artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 741 +++++++++++------ artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 741 +++++++++++------ docs/chatgpt-desktop-cdp.md | 13 +- src/cli/chatgpt-desktop/read.tsx | 31 +- src/cli/chatgpt-desktop/send.tsx | 10 +- src/core/chatgpt-desktop/adapter.ts | 29 +- .../chatgpt-desktop/app-server-fallback.ts | 22 +- src/core/chatgpt-desktop/cdp-adapter.ts | 145 ++-- src/core/chatgpt-desktop/cdp-dom.ts | 639 ++++++++++----- src/core/chatgpt-desktop/facade.ts | 28 +- src/core/chatgpt-desktop/index.ts | 10 +- src/core/chatgpt-desktop/routes.ts | 38 +- src/core/chatgpt-desktop/types.ts | 11 + .../tools/chatgpt_desktop_read_thread.tsx | 11 +- .../grok-bot/tools/chatgpt_desktop_send.tsx | 11 +- .../tools/chatgpt_desktop_wait_reply.tsx | 4 +- tests/route-unit/chatgpt-desktop.test.ts | 65 +- 21 files changed, 2747 insertions(+), 1281 deletions(-) diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 0e499cb..33c84a2 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"08b47068d7470c44ad8b35f8d84dd2440f6fcc00674139231e2431e7c5d70bcc"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"90755468ff34ba30d11ec8481b8a60b499f8d8b531d0a2d3b6cd1d8565b1cd68"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"0020602bdb7f33ddda058b4d1424edd9a3dcf2ef9d69419e0f7af3f37ae4864b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"f661f7a8ce1f2856f5ab7b3a36043e514704e6924d80f4746ad3222a08f6bb08"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"f78f26a4b393e59fb8f9fe2d3fcc5a7decbef73ac76eb9533a1606a8799d3d8d"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"8b3b37f397b7a6d6a65cb480cbee04eb86c5cd6eb3410590ee98d4c6688f8956"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"079ac33ba4d609c7407458d5fb170606801214f13dc8e7c12e543bc276055ec4"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"92f2960c28377bcfbbc44f2f10906e9e02ef8a5d021eb536d74adc05ad12dfb3"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index e7b6077..d49df6d 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"a36888d23691b58e54be76e21b0fecf246832e06dc1328140fb31fa5253e366c","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"22e4e18e64995f3c7e3acf25c9138344ff6c6b01f0fa6d36dabfaa1d65acc839","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"f4135bee52844417625ab940db9c733d028452dd10b7fd7d3816e7d33563c445"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"74f9a2a23bf23c9e496fe7fa893f1fad6cf018e35dc0ada37cc84c1cdef5644f"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"8b3538068d035d1147916a0f43c8cb24a58e98733c624c18e102eee60184d7ac"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"cd1284db2027910b91c8f0ae7ce1d7c476c7917708018f75f5b7d73088c020de"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"7a2e819d5fc9b29660cf05d5c687165d73af5a0e553460b77e46d53ecad55372"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"fd3c13ab04777bec512e8012d4a3397605719b60887c3d60b24c54c8a2480b57"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"5280b364c75e06e5f00c254f23c21b04144e949590da0c4b02e1c2cbe582aec8"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"994bafdb1ebcd71e4bb997d66d37ad3e4fe202d72258a1408f67b63c152c888f"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"0a39297107040b2a488f6401b7b06d95bc93260318772f1fbc9d2faba2c8510b"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"af1e60e24df9d3256cc5a3cfea6afe9634c6264a8cbb807f1d4b2aaa411115db"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"20e21bf5a851b23a2e42bdf3dbdec479128f65c38ec0fc1e40c9c7d2bb2a3d27"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"56a8ea6c9618831131cdf16bb60e1b0e764a4f8c72c9557d926db94f5b7090b8"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"892e6afecb66d26ba228e35c95694563a206c29d11fbb36e24889a2668e98780"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"da1e1d85f8673af3bcdbf3f23425d75d3db7a5c6080c26bc9e902b643720316f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"f6586c0913fa64da29f9c1bd4b2ada95aefdd014eea80e802822c332d1e3aba6"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"37a181c673a583a5c0344a10367ee7222cd5aa480f10351b3b337c8c9ef62cb6"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"7dfb0e5cd0117ac38650f83ce257e35f77fe71398b5e5e48c695abbf4d2d7e6c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"7695a3ef40496df91e8d60ba248983c89b1ebdbb3f07e2ec8ffdc2271d33a85d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"976ad8b1c1fc8dae4abe07e2dcbbbb56233f467fd06b1a25d2f4ca056b38ce69"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"327e7c61d5849c82b3bb864286f207ced8979ea546b365b708c7070715501151"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"bb0f72145123dde9bf4438b9f863ddaf4781656972b17f15368c0949145f9c91"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"1ae06583bac9ae9add3371b4b5c77697c6c7492dcd1c0be1a72501876879ae76"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"56454a78aaea180d78e8cd62385ef66261f1748b593aa5165e587d5975205af4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"ee26dc07b4baade26d8154ed7b4cb69c24285f2997f016bbfb8607e728e7e6bb"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"cb29cb40fdae0929649123705142adb75c108e689ffa90901737071d7e0d5bbc"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7bfaf1abfe75bc5c2167d9053c76d33ed830a083780d2dc3017492ec3c44799d"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":21751,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"4c107ff9b3c621f9555e173ed827a1d69421fb55348579bf748738afdf8b1202"},{"bytes":1419460,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"08b47068d7470c44ad8b35f8d84dd2440f6fcc00674139231e2431e7c5d70bcc"},{"bytes":2276421,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"90755468ff34ba30d11ec8481b8a60b499f8d8b531d0a2d3b6cd1d8565b1cd68"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1334328,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"0020602bdb7f33ddda058b4d1424edd9a3dcf2ef9d69419e0f7af3f37ae4864b"},{"bytes":3160092,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"f661f7a8ce1f2856f5ab7b3a36043e514704e6924d80f4746ad3222a08f6bb08"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281157,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.","exitCode":"result","options":[{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":100,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":100,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start/use a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"a17943a11b9925112cf456b4c5466766a4bd80ec3daeea646798c750ed354516","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend \"cdp\" or \"app-server\".","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"limit":{"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start/use a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"098bbb556ee7a042e0f284eae7583f832d68926d29970d68fc9de9ddb8750d34","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"d112a572f8a7219a9bc731d0f58f3932b2e8669d42e910acd3962361ec3af32c","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"f4135bee52844417625ab940db9c733d028452dd10b7fd7d3816e7d33563c445"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"315374cf23e0dcdac5207843f0bb8d50198b2191ff33e081f106af1c52f2f556"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"8b3538068d035d1147916a0f43c8cb24a58e98733c624c18e102eee60184d7ac"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"49269496e4dd7866bb7a421aac5743bf929b32bc08ed890188837f43a68f1550"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"fd3c13ab04777bec512e8012d4a3397605719b60887c3d60b24c54c8a2480b57"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"5280b364c75e06e5f00c254f23c21b04144e949590da0c4b02e1c2cbe582aec8"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"cb17b333ac3a50988b6146f6e9b1d76bb2805c8c5073692269f3bd424a504891"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"056613a78d6a247315089c685a0856fd09202fe7cda84c8f3cc892cd04bea521"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"8a45cab48d9f02da4fa2118e0a238696ab2f4ee198faff45ac64580c1f687d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"bd7013ebac4d75e925490fc5fff371f11c87e273c9f0e9530bfb8c306e8afaac"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"56a8ea6c9618831131cdf16bb60e1b0e764a4f8c72c9557d926db94f5b7090b8"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"3a789ff68a7fd4423bc75330e8da671bf781edae1cc131b33f09c5b655d97ae7"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"2ba2372ee09b7e2814e55804907e8659a5c4e518aaa4ded3744c23218e93f30a"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"eb8a53996735657a335b96e6a1f591046aa554d144fdfc12958fbc4e64e59648"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"0e7dd4f7c395805e7071c8188b6fd28452c423b4b8ba341c7b4a8ebb2c5e28a6"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"7dfb0e5cd0117ac38650f83ce257e35f77fe71398b5e5e48c695abbf4d2d7e6c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"7695a3ef40496df91e8d60ba248983c89b1ebdbb3f07e2ec8ffdc2271d33a85d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"50a243585c7e003cb7d2d902a3959ada5129773897901f5253b84aa55ad9652f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"f8db4c6394ff4cf0cbc673468dd16e68365449901e83bd5e9850ce0fa324cb10"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"bb0f72145123dde9bf4438b9f863ddaf4781656972b17f15368c0949145f9c91"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"97e7b53952b5d83d2b0d2f4b0f5576276d6c8bf1310a258a60a6f256ea4443f9"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"56454a78aaea180d78e8cd62385ef66261f1748b593aa5165e587d5975205af4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"ee26dc07b4baade26d8154ed7b4cb69c24285f2997f016bbfb8607e728e7e6bb"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"af5058a1cc68c9d67b940a1943dfa0e9f1988c6f1b37884a4caba352c011f75a"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7bfaf1abfe75bc5c2167d9053c76d33ed830a083780d2dc3017492ec3c44799d"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":21751,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"109855d6f2c090b1edb56b6aac81fabb6cda02a48ef733721707d922e36d6090"},{"bytes":1432235,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"f78f26a4b393e59fb8f9fe2d3fcc5a7decbef73ac76eb9533a1606a8799d3d8d"},{"bytes":2290709,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"8b3b37f397b7a6d6a65cb480cbee04eb86c5cd6eb3410590ee98d4c6688f8956"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1348151,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"079ac33ba4d609c7407458d5fb170606801214f13dc8e7c12e543bc276055ec4"},{"bytes":3174043,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"92f2960c28377bcfbbc44f2f10906e9e02ef8a5d021eb536d74adc05ad12dfb3"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281157,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via CDP. Default: visible turns. --full wheel-crawls history.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via CDP. Default: visible turns. --full wheel-crawls history.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, wheel-crawl older history (slow). Default false = visible turns only.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"c90c683bb79425d235dd2c4dd08d0064b2ffad24ceb96adbec8cd26e42eb2784","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend \"cdp\" or \"app-server\".","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Open a ChatGPT Desktop sidebar thread (waits for Loading task… up to openTimeoutMs, default 90s) and harvest turns via local CDP. Default is visible turns only; full=true mouse-wheels the column-reverse timeline for history (skips history-gap placeholders). Falls back to Codex app-server when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, wheel-crawl older history (slow). Default false = visible turns only.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Falls back to app-server send when CDP is down and threadId is set.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). Falls back to app-server polling when CDP is unreachable.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index 2bf21c9..4bd9752 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -8616,7 +8616,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).', + description: 'Read a ChatGPT Desktop thread via CDP. Default: visible turns. --full wheel-crawls history.', exitCode: 'result', positionals: [ 'threadId' @@ -8624,10 +8624,18 @@ var __webpack_modules__ = { inputJsonSchema: { additionalProperties: false, properties: { + full: { + default: false, + type: 'boolean' + }, limit: { default: 100, type: 'number' }, + openTimeoutMs: { + default: 90000, + type: 'number' + }, port: { type: 'number' }, @@ -8639,10 +8647,15 @@ var __webpack_modules__ = { 'threadId' ], type: 'object' + }, + render: { + maxElapsedMs: 660000 } }; const inputSchema = zod__rspack_import_2.Ikc({ - limit: zod__rspack_import_2.aig().int().min(1).max(500).default(100), + full: zod__rspack_import_2.zMY().default(false), + limit: zod__rspack_import_2.aig().int().min(1).max(2000).default(100), + openTimeoutMs: zod__rspack_import_2.aig().int().min(1).max(600000).default(90000), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), threadId: zod__rspack_import_2.YjP().min(1).max(256) }).strict(); @@ -8651,8 +8664,12 @@ var __webpack_modules__ = { const turns = Array.isArray(out.turns) ? out.turns : []; const text = turns.length > 0 ? turns.map((turn)=>{ const row = turn; - return `[${row.role ?? '?'} ${row.turnKey ?? ''}] ${row.text ?? ''}`; - }).join('\n\n') + `\n\nbackend: ${String(out.backend ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); + const body = row.userText || row.assistantText ? [ + row.userText ? `user: ${row.userText}` : null, + row.assistantText ? `assistant: ${row.assistantText}` : null + ].filter(Boolean).join('\n') : row.text ?? ''; + return `[${row.role ?? '?'} ${row.turnKey ?? ''}]\n${body}`; + }).join('\n\n') + `\n\nbackend: ${String(out.backend ?? '')} full: ${String(out.full ?? false)}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { value: out, children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { @@ -8675,7 +8692,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.', + description: 'Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .', exitCode: 'result', positionals: [ 'text' @@ -8683,9 +8700,15 @@ var __webpack_modules__ = { inputJsonSchema: { additionalProperties: false, properties: { + openTimeoutMs: { + type: 'number' + }, port: { type: 'number' }, + project: { + type: 'string' + }, text: { type: 'array', items: { @@ -8702,11 +8725,13 @@ var __webpack_modules__ = { type: 'object' }, render: { - maxElapsedMs: 120000 + maxElapsedMs: 180000 } }; const inputSchema = zod__rspack_import_2.Ikc({ + openTimeoutMs: zod__rspack_import_2.aig().int().min(1).max(600000).default(90000), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), + project: zod__rspack_import_2.YjP().min(1).max(256).optional(), text: zod__rspack_import_2.YOg(zod__rspack_import_2.YjP()).min(1), threadId: zod__rspack_import_2.YjP().min(1).max(256).optional() }).strict(); @@ -8714,7 +8739,9 @@ var __webpack_modules__ = { const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.UP)({ port: input.port, threadId: input.threadId, - text: input.text.join(' ').trim() + text: input.text.join(' ').trim(), + project: input.project, + openTimeoutMs: input.openTimeoutMs }); return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { value: out, @@ -11119,7 +11146,7 @@ var __webpack_modules__ = { })) }; } - async function appServerReadThread({ threadId, limit = 100 }) { + async function appServerReadThread({ threadId, limit = 100, full = false }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { let turns = []; @@ -11128,7 +11155,9 @@ var __webpack_modules__ = { threadId }); const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - turns = normalizeTurns(raw).slice(-limit); + turns = normalizeTurns(raw).slice(full ? 0 : -limit); + if (full && limit > 0) turns = turns.slice(0, limit); + else if (!full) turns = turns.slice(-limit); } catch { const items = await client.request('thread/items/list', { threadId, @@ -11140,7 +11169,8 @@ var __webpack_modules__ = { threadId, turns, backend: 'app-server', - limit + limit, + full }; } finally{ client.close(); @@ -11165,7 +11195,16 @@ var __webpack_modules__ = { message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined }; } - async function appServerWaitForReply({ threadId, timeoutMs = 60000 }) { + async function appServerWaitForReply({ threadId = 'unknown', timeoutMs = 60000 }) { + if (!threadId || threadId === 'unknown' || threadId === 'new') { + return { + threadId: threadId || 'unknown', + reply: '', + backend: 'app-server', + experimental: false, + delivery: 'rejected' + }; + } const baseline = await appServerReadThread({ threadId, limit: 200 @@ -11289,80 +11328,92 @@ var __webpack_modules__ = { limit }; } - async readThread({ threadId, limit = 100 }) { + async readThread({ threadId, limit = 100, full = false, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - await delay(150); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { - limit + limit, + full, + threadId }); return { threadId, turns, backend: 'cdp', - limit + limit, + full }; } - async sendMessage({ threadId, text }) { + async sendMessage({ threadId, text, project, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); + let temporaryThreadId; + let resolvedThreadId = threadId ?? 'new'; if (threadId) { - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - await delay(100); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); + } else { + await (0, _cdp_dom_js__rspack_import_2.s0)(this.#requireSession(), sessionId, { + project + }); + await delay(300); + const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + limit: 20 + }); + const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); + if (temp) { + temporaryThreadId = temp.threadId; + resolvedThreadId = temp.threadId; + } } - await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); return { - threadId: threadId ?? 'new', + threadId: resolvedThreadId, + temporaryThreadId, + project, backend: 'cdp', - experimental: true, + experimental: false, delivery: 'accepted', - message: 'Submitted via experimental CDP composer path' + sentVia, + message: 'Submitted via CDP composer (focus → insertText → Enter)' }; } - async waitForReply({ threadId, timeoutMs = 60000 }) { + async waitForReply({ threadId, timeoutMs = 120000 }) { const sessionId = await this.#ensurePageSession(); - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - const deadline = Date.now() + timeoutMs; - let previousKeys = new Set(); - let lastAssistant = ''; - let stable = 0; - const baseline = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { - limit: 500 - }); - previousKeys = new Set(baseline.map((t)=>t.turnKey)); - while(Date.now() < deadline){ - await delay(400); - const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { - limit: 500 + if (threadId && !threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && threadId !== 'new') { + try { + await this.#openAndWait(sessionId, threadId, 90000); + } catch {} + } + const baseline = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); + try { + const done = await (0, _cdp_dom_js__rspack_import_2.FG)(this.#requireSession(), sessionId, { + timeoutMs, + baselineFinalCount: baseline.finalAssistantCount }); - const fresh = turns.filter((t)=>!previousKeys.has(t.turnKey) && t.role === 'assistant'); - const candidate = fresh.at(-1)?.text ?? ''; - if (candidate && candidate === lastAssistant) { - stable += 1; - if (stable >= 3) { - return { - threadId, - reply: candidate, - backend: 'cdp', - experimental: true, - delivery: 'replied' - }; - } - } else if (candidate) { - lastAssistant = candidate; - stable = 0; - } + const resolvedId = done.conversationId || threadId || 'unknown'; + return { + threadId: resolvedId, + conversationId: done.conversationId || undefined, + reply: done.reply, + backend: 'cdp', + experimental: false, + delivery: 'replied' + }; + } catch (error) { + const last = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); + return { + threadId: last.conversationId || threadId || 'unknown', + conversationId: last.conversationId || undefined, + reply: last.reply, + backend: 'cdp', + experimental: false, + delivery: last.reply ? 'replied' : 'timeout', + ...error instanceof Error ? {} : {} + }; } - return { - threadId, - reply: lastAssistant, - backend: 'cdp', - experimental: true, - delivery: lastAssistant ? 'replied' : 'timeout' - }; } - async openThread(threadId) { + async openThread(threadId, { openTimeoutMs = 90000 } = {}) { const sessionId = await this.#ensurePageSession(); - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); return { threadId, backend: 'cdp' @@ -11410,6 +11461,12 @@ var __webpack_modules__ = { this.#session?.close(); this.#session = null; } + async #openAndWait(sessionId, threadId, openTimeoutMs) { + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { + timeoutMs: openTimeoutMs + }); + } async #attachMainWindow() { const targets = await this.listTargets(); const main = (0, _cdp_dom_js__rspack_import_2.C2)(targets); @@ -11463,32 +11520,41 @@ var __webpack_modules__ = { turnKey: 'data-turn-key', userBubble: 'data-user-message-bubble', timelineScroll: 'data-app-action-timeline-scroll', - virtualizedTurn: 'data-virtualized-turn-content' + virtualizedTurn: 'data-virtualized-turn-content', + composer: 'data-codex-composer', + finalAssistant: 'data-local-conversation-final-assistant', + markdownTextStyle: 'data-markdown-text-style', + conversationAnnotation: 'data-response-annotation-conversation' }; const MAIN_CONTENT_SURFACE_CLASS_PREFIX = '_MainContentSurface'; - const COMPOSER_SELECTORS = [ - 'main [contenteditable="true"]', - 'main textarea', - '[data-app-action-composer] [contenteditable="true"]', - '[data-app-action-composer] textarea', - 'form [contenteditable="true"]', - 'form textarea' - ]; - const SEND_BUTTON_SELECTORS = [ - 'button[data-app-action-send]', - 'button[aria-label="Send"]', - 'button[aria-label="Send message"]', - 'main button[type="submit"]' - ]; + const HISTORY_GAP_PREFIX = 'history-gap:'; + const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; + const LOADING_TASK_TEXT = 'Loading task…'; + const DEFAULT_OPEN_TIMEOUT_MS = 90000; + const DEFAULT_FULL_READ_IDLE_WHEELS = 8; + const DEFAULT_FULL_READ_MAX_WHEELS = 400; + const COMPOSER_SELECTOR = `[${ATTR.composer}="true"][contenteditable="true"]`; + const SEND_BUTTON_SELECTOR = 'button[aria-label="Send"]'; + const STOP_BUTTON_SELECTOR = 'main button[aria-label="Stop"]'; + const FINAL_ASSISTANT_SELECTOR = `[${ATTR.finalAssistant}="true"]`; + const ASSISTANT_MESSAGE_SELECTOR = `[${ATTR.finalAssistant}="true"] [${ATTR.markdownTextStyle}="assistant-message"]`; + const CONVERSATION_ANNOTATION_SELECTOR = `[${ATTR.conversationAnnotation}]`; const SELECTORS = { threadRow: `[role="button"][${ATTR.threadRow}]`, turn: `[${ATTR.turnKey}]`, userBubble: `[${ATTR.userBubble}]`, timelineScroll: `[${ATTR.timelineScroll}]`, - mainSurface: 'main', - composerCandidates: COMPOSER_SELECTORS, - sendButtonCandidates: SEND_BUTTON_SELECTORS + composer: COMPOSER_SELECTOR, + sendButton: SEND_BUTTON_SELECTOR, + stopButton: STOP_BUTTON_SELECTOR, + finalAssistant: FINAL_ASSISTANT_SELECTOR, + assistantMessage: ASSISTANT_MESSAGE_SELECTOR, + conversationAnnotation: CONVERSATION_ANNOTATION_SELECTOR, + newChatFallback: 'button' }; + function newChatInProjectSelector(project) { + return `button[aria-label=${JSON.stringify(`Start new chat in ${project}`)}]`; + } function isMainWindowTarget(target) { if (target.type !== 'page') return false; const url = typeof target.url === 'string' ? target.url : ''; @@ -11507,15 +11573,33 @@ var __webpack_modules__ = { function pickMainWindowTarget(targets) { return targets.find((t)=>isMainWindowTarget(t)) ?? null; } + function dedupeThreadsById(threads) { + const seen = new Set(); + const out = []; + for (const thread of threads){ + if (!thread.threadId || seen.has(thread.threadId)) continue; + seen.add(thread.threadId); + out.push(thread); + } + return out; + } const LIST_THREADS_EXPRESSION = `(() => { const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); - return rows.map((row) => ({ - threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || '', - title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), - pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', - selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', - kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', - })).filter((t) => t.threadId); + const seen = new Set(); + const out = []; + for (const row of rows) { + const threadId = row.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''; + if (!threadId || seen.has(threadId)) continue; + seen.add(threadId); + out.push({ + threadId, + title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), + pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', + selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', + kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + }); + } + return out; })()`; function openThreadExpression(threadId) { return `(() => { @@ -11527,7 +11611,69 @@ var __webpack_modules__ = { return { ok: true, threadId: id }; })()`; } - const READ_THREAD_EXPRESSION = `(() => { + function startNewChatExpression(project) { + const projectSel = project ? newChatInProjectSelector(project) : null; + return `(() => { + const projectSel = ${JSON.stringify(projectSel)}; + if (projectSel) { + const preferred = document.querySelector(projectSel); + if (preferred) { + preferred.click(); + return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; + } + } + const buttons = Array.from(document.querySelectorAll('button')); + const fallback = buttons.find((btn) => (btn.textContent || '').trim() === 'New chat'); + if (!fallback) return { ok: false, error: 'new-chat-not-found' }; + fallback.click(); + return { ok: true, via: 'fallback' }; + })()`; + } + const LOADING_TASK_GONE_EXPRESSION = `(() => { + const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; + const mains = Array.from(document.querySelectorAll('main')); + const surface = + mains.find((el) => typeof el.className === 'string' && el.className.includes(surfacePrefix)) + || (mains.length >= 2 ? mains[1] : null) + || mains[0] + || document.body; + const text = (surface.innerText || '').replace(/\\u2026/g, '…'); + return !text.includes(${JSON.stringify(LOADING_TASK_TEXT)}); +})()`; + const FOCUS_COMPOSER_EXPRESSION = `(() => { + const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.focus(); + return { ok: true }; +})()`; + const REPLY_STATE_EXPRESSION = `(() => { + const stop = document.querySelector(${JSON.stringify(STOP_BUTTON_SELECTOR)}); + const finals = Array.from(document.querySelectorAll(${JSON.stringify(FINAL_ASSISTANT_SELECTOR)})); + const lastFinal = finals.at(-1) || null; + const annotation = lastFinal + ? lastFinal.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}) + || lastFinal.closest(${JSON.stringify(SELECTORS.turn)})?.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}) + : document.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}); + const conversationId = annotation + ? (annotation.getAttribute(${JSON.stringify(ATTR.conversationAnnotation)}) || '') + : ''; + const messageEl = lastFinal + ? lastFinal.querySelector(${JSON.stringify(`[${ATTR.markdownTextStyle}="assistant-message"]`)}) + : null; + const reply = messageEl ? (messageEl.innerText || '').trim() : ''; + const turns = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.turn)})); + const lastTurn = turns.at(-1); + const lastTurnKey = lastTurn ? (lastTurn.getAttribute(${JSON.stringify(ATTR.turnKey)}) || '') : ''; + return { + stopVisible: Boolean(stop), + finalAssistantCount: finals.length, + conversationId, + reply, + lastTurnKey, + }; +})()`; + const HARVEST_VISIBLE_TURNS_EXPRESSION = `(() => { + const gapPrefix = ${JSON.stringify(HISTORY_GAP_PREFIX)}; const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); const surface = @@ -11539,114 +11685,51 @@ var __webpack_modules__ = { surface.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}) || document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); const root = scroll || surface; - const collected = new Map(); - const statusRe = /^Worked for \\d+s$/i; - const harvest = () => { - for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { - const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; - if (!turnKey || collected.has(turnKey)) continue; - const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); - const text = (el.innerText || '').trim(); - let role = 'assistant'; - if (user) role = 'user'; - else if (!text || statusRe.test(text)) role = 'status'; - collected.set(turnKey, { turnKey, role, text }); + const out = []; + for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { + const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; + if (!turnKey || turnKey.startsWith(gapPrefix)) continue; + const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); + const assistant = el.querySelector(${JSON.stringify(ASSISTANT_MESSAGE_SELECTOR)}); + const userText = user ? (user.innerText || '').trim() : ''; + const assistantText = assistant ? (assistant.innerText || '').trim() : ''; + const raw = (el.innerText || '').trim(); + const statusRe = /^Worked for \\d+s$/i; + let role = 'assistant'; + let text = assistantText || userText || raw; + if (user && !assistantText) { + role = 'user'; + text = userText || raw; + } else if (assistantText) { + role = 'assistant'; + text = assistantText; + } else if (!raw || statusRe.test(raw)) { + role = 'status'; + text = raw; } - }; - const maxPasses = 80; - let stable = 0; - let lastSize = -1; - if (scroll) scroll.scrollTop = 0; - for (let i = 0; i < maxPasses; i++) { - harvest(); - if (collected.size === lastSize) { - stable += 1; - if (stable >= 3) break; - } else { - stable = 0; - lastSize = collected.size; - } - if (scroll) { - const next = Math.min(scroll.scrollHeight, scroll.scrollTop + Math.max(scroll.clientHeight, 200)); - if (next <= scroll.scrollTop && stable >= 1) break; - scroll.scrollTop = next; - } else { - break; - } - } - harvest(); - return Array.from(collected.values()); -})()`; - const FOCUS_COMPOSER_EXPRESSION = `(() => { - const composers = ${JSON.stringify([ - ...COMPOSER_SELECTORS - ])}; - for (const sel of composers) { - const composer = document.querySelector(sel); - if (!composer) continue; - composer.focus(); - return { ok: true, selector: sel, contentEditable: !!composer.isContentEditable }; + out.push({ turnKey, role, text, userText, assistantText }); } - return { ok: false, error: 'composer-not-found' }; + return out; })()`; - function fillComposerExpression(text) { - return `(() => { - const text = ${JSON.stringify(text)}; - const composers = ${JSON.stringify([ - ...COMPOSER_SELECTORS - ])}; - let composer = null; - for (const sel of composers) { - composer = document.querySelector(sel); - if (composer) break; - } - if (!composer) return { ok: false, error: 'composer-not-found' }; - composer.focus(); - if (composer.isContentEditable) { - composer.textContent = text; - composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: text, inputType: 'insertText' })); - } else if ('value' in composer) { - composer.value = text; - composer.dispatchEvent(new Event('input', { bubbles: true })); - } else { - return { ok: false, error: 'composer-unsupported' }; - } - return { ok: true }; - })()`; - } - const SUBMIT_COMPOSER_EXPRESSION = `(() => { - const buttons = ${JSON.stringify([ - ...SEND_BUTTON_SELECTORS - ])}; - for (const sel of buttons) { - const btn = document.querySelector(sel); - if (btn && !btn.disabled) { - btn.click(); - return { ok: true, sentVia: 'button', selector: sel }; - } - } - const composers = ${JSON.stringify([ - ...COMPOSER_SELECTORS - ])}; - let composer = null; - for (const sel of composers) { - composer = document.querySelector(sel); - if (composer) break; - } - if (!composer) return { ok: false, error: 'composer-not-found' }; - composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); - composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); - return { ok: true, sentVia: 'enter' }; + const TIMELINE_SCROLL_METRICS_EXPRESSION = `(() => { + const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + if (!scroll) return { ok: false }; + const rect = scroll.getBoundingClientRect(); + return { + ok: true, + x: Math.floor(rect.left + rect.width / 2), + y: Math.floor(rect.top + Math.min(rect.height / 2, 120)), + scrollTop: scroll.scrollTop, + scrollHeight: scroll.scrollHeight, + clientHeight: scroll.clientHeight, + }; })()`; - function sendMessageExpression(text) { - return fillComposerExpression(text); - } async function listThreadsFromDom(session, sessionId, { limit = 50 } = {}) { const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { sessionId }); if (!Array.isArray(rows)) return []; - return rows.slice(0, limit).map((row)=>({ + return dedupeThreadsById(rows).slice(0, limit).map((row)=>({ threadId: String(row.threadId), title: String(row.title ?? ''), pinned: Boolean(row.pinned), @@ -11662,60 +11745,213 @@ var __webpack_modules__ = { throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); } } - async function readTurnsFromDom(session, sessionId, { limit = 100 } = {}) { - const turns = await session.evaluate(READ_THREAD_EXPRESSION, { + async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS } = {}) { + const deadline = Date.now() + timeoutMs; + while(Date.now() < deadline){ + const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { + sessionId + }); + if (gone) return; + await delay(250); + } + throw new Error(`ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); + } + async function startNewChatInDom(session, sessionId, { project } = {}) { + const result = await session.evaluate(startNewChatExpression(project), { sessionId }); - if (!Array.isArray(turns)) return []; - return turns.slice(-limit).map((turn)=>({ - turnKey: String(turn.turnKey), - role: turn.role === 'user' || turn.role === 'status' ? turn.role : 'assistant', - text: String(turn.text ?? '') - })); + if (!result?.ok) { + throw new Error(project ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` : 'ChatGPT Desktop "New chat" button not found'); + } + return { + via: result.via ?? 'unknown' + }; } - async function sendMessageInDom(session, sessionId, text) { + async function focusComposer(session, sessionId) { const focused = await session.evaluate(FOCUS_COMPOSER_EXPRESSION, { sessionId }); if (!focused?.ok) { - throw new Error('ChatGPT Desktop composer not found (experimental send path)'); - } - let inserted = false; - try { - await session.send('Input.insertText', { - text - }, { - sessionId - }); - inserted = true; - } catch { - inserted = false; + throw new Error('ChatGPT Desktop composer not found ([data-codex-composer=true])'); } - if (!inserted) { - const filled = await session.evaluate(fillComposerExpression(text), { - sessionId - }); - if (!filled?.ok) { - throw new Error(filled?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${filled?.error ?? 'fill-failed'}`); - } + } + async function submitComposerWithEnter(session, sessionId) { + const base = { + windowsVirtualKeyCode: 13, + code: 'Enter', + key: 'Enter', + text: '\r', + unmodifiedText: '\r' + }; + await session.send('Input.dispatchKeyEvent', { + type: 'rawKeyDown', + ...base + }, { + sessionId + }); + await session.send('Input.dispatchKeyEvent', { + type: 'char', + ...base + }, { + sessionId + }); + await session.send('Input.dispatchKeyEvent', { + type: 'keyUp', + ...base + }, { + sessionId + }); + } + async function submitComposerWithButton(session, sessionId) { + const result = await session.evaluate(`(() => { + const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); + if (!btn || btn.disabled) return { ok: false }; + btn.click(); + return { ok: true }; + })()`, { + sessionId + }); + return Boolean(result?.ok); + } + async function sendMessageInDom(session, sessionId, text) { + await focusComposer(session, sessionId); + await session.send('Input.insertText', { + text + }, { + sessionId + }); + await submitComposerWithEnter(session, sessionId); + const sendStillVisible = await session.evaluate(`(() => { + const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); + return Boolean(btn && !btn.disabled); + })()`, { + sessionId + }); + if (sendStillVisible) { + const clicked = await submitComposerWithButton(session, sessionId); + if (clicked) return { + sentVia: 'button' + }; } - const submitted = await session.evaluate(SUBMIT_COMPOSER_EXPRESSION, { + return { + sentVia: 'enter' + }; + } + async function readReplyState(session, sessionId) { + const state = await session.evaluate(REPLY_STATE_EXPRESSION, { sessionId }); - if (!submitted?.ok) { - throw new Error(`ChatGPT Desktop send submit failed: ${submitted?.error ?? 'unknown'}`); + return { + stopVisible: Boolean(state?.stopVisible), + finalAssistantCount: Number(state?.finalAssistantCount ?? 0), + conversationId: String(state?.conversationId ?? ''), + reply: String(state?.reply ?? ''), + lastTurnKey: String(state?.lastTurnKey ?? '') + }; + } + async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0 } = {}) { + const deadline = Date.now() + timeoutMs; + let sawStop = false; + const started = Date.now(); + while(Date.now() < deadline){ + const state = await readReplyState(session, sessionId); + if (state.stopVisible) sawStop = true; + const hasNewFinal = state.finalAssistantCount > baselineFinalCount && Boolean(state.reply); + if (!state.stopVisible && hasNewFinal && (sawStop || Date.now() - started > 1500)) { + return { + reply: state.reply, + conversationId: state.conversationId + }; + } + await delay(200); } + const last = await readReplyState(session, sessionId); + if (!last.stopVisible && last.finalAssistantCount > baselineFinalCount && last.reply) { + return { + reply: last.reply, + conversationId: last.conversationId + }; + } + throw new Error(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); + } + function normalizeTurn(raw) { + const role = raw.role === 'user' || raw.role === 'status' || raw.role === 'assistant' ? raw.role : raw.assistantText ? 'assistant' : raw.userText ? 'user' : 'assistant'; return { - sentVia: submitted.sentVia ?? (inserted ? 'insertText' : 'dom') + turnKey: String(raw.turnKey ?? ''), + role, + text: String(raw.text ?? raw.assistantText ?? raw.userText ?? ''), + userText: raw.userText ? String(raw.userText) : undefined, + assistantText: raw.assistantText ? String(raw.assistantText) : undefined + }; + } + async function harvestVisibleTurns(session, sessionId) { + const rows = await session.evaluate(HARVEST_VISIBLE_TURNS_EXPRESSION, { + sessionId + }); + if (!Array.isArray(rows)) return []; + return rows.map(normalizeTurn).filter((t)=>t.turnKey && !t.turnKey.startsWith(HISTORY_GAP_PREFIX)); + } + async function readTurnsFromDom(session, sessionId, { limit = 100, full = false, threadId, idleWheels = DEFAULT_FULL_READ_IDLE_WHEELS, maxWheels = DEFAULT_FULL_READ_MAX_WHEELS } = {}) { + const collected = new Map(); + const ingest = async ()=>{ + for (const turn of (await harvestVisibleTurns(session, sessionId))){ + collected.set(turn.turnKey, turn); + } }; + await ingest(); + if (!full) { + const visible = [ + ...collected.values() + ]; + return limit > 0 ? visible.slice(-limit) : visible; + } + let idle = 0; + for(let step = 0; step < maxWheels; step++){ + const before = collected.size; + const metrics = await session.evaluate(TIMELINE_SCROLL_METRICS_EXPRESSION, { + sessionId + }); + if (!metrics?.ok || metrics.x == null || metrics.y == null) break; + await session.send('Input.dispatchMouseEvent', { + type: 'mouseWheel', + x: metrics.x, + y: metrics.y, + deltaX: 0, + deltaY: -800 + }, { + sessionId + }); + await delay(120); + await ingest(); + if (collected.size === before) { + idle += 1; + if (idle >= idleWheels) break; + } else { + idle = 0; + } + if (threadId && collected.has(threadId)) break; + } + const all = [ + ...collected.values() + ]; + return limit > 0 ? all.slice(0, limit) : all; + } + function delay(ms) { + return new Promise((resolve)=>setTimeout(resolve, ms)); } __webpack_require__.d(__webpack_exports__, { AY: ()=>listThreadsFromDom, C2: ()=>pickMainWindowTarget, + FG: ()=>waitForReplyDone, JU: ()=>readTurnsFromDom, Kl: ()=>openThreadInDom, Mr: ()=>summarizeTargetInfos, - lh: ()=>sendMessageInDom + YX: ()=>readReplyState, + Zx: ()=>waitForLoadingTaskGone, + lh: ()=>sendMessageInDom, + s0: ()=>startNewChatInDom + }, { + hA: TEMP_THREAD_ID_PREFIX }); }, "./src/core/chatgpt-desktop/cdp-session.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -11981,13 +12217,16 @@ var __webpack_modules__ = { return await this.#cdp.waitForReply(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return this.#fallbacks.waitForReply(options); + return this.#fallbacks.waitForReply({ + threadId: options.threadId ?? 'unknown', + timeoutMs: options.timeoutMs + }); } } - async openThread(threadId) { + async openThread(threadId, options) { try { await this.#ensureCdp(); - return await this.#cdp.openThread(threadId); + return await this.#cdp.openThread(threadId, options); } catch (error) { if (!isCdpFailure(error)) throw error; return this.#fallbacks.openThread(threadId); @@ -12124,17 +12363,21 @@ var __webpack_modules__ = { const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, - limit: zod__rspack_import_4.aig().int().min(1).max(500).default(100) + limit: zod__rspack_import_4.aig().int().min(1).max(2000).default(100), + full: zod__rspack_import_4.zMY().default(false), + openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); const sendSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), - text: zod__rspack_import_4.YjP().min(1).max(100000) + text: zod__rspack_import_4.YjP().min(1).max(100000), + project: zod__rspack_import_4.YjP().min(1).max(256).optional(), + openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); const waitReplySchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), - threadId, - timeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(60000) + threadId: threadId.optional(), + timeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(120000) }).strict(); const resultSchema = zod__rspack_import_4.Ikc({ exitCode: zod__rspack_import_4.KCZ([ @@ -12153,7 +12396,8 @@ var __webpack_modules__ = { return run(adapter); } function asResult(value) { - return resultSchema.parse(value); + const cleaned = Object.fromEntries(Object.entries(value).filter(([, entry])=>entry !== undefined)); + return resultSchema.parse(cleaned); } function mapError(error) { if (error instanceof _errors_js__rspack_import_1.EH) { @@ -12199,7 +12443,9 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ threadId: input.threadId, - limit: input.limit + limit: input.limit, + full: input.full, + openTimeoutMs: input.openTimeoutMs })); return asResult({ ...out, @@ -12213,7 +12459,9 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.sendMessage({ threadId: input.threadId, - text: input.text + text: input.text, + project: input.project, + openTimeoutMs: input.openTimeoutMs })); return asResult({ ...out, @@ -12248,13 +12496,15 @@ var __webpack_modules__ = { return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { - return `${result.turns.length} turns on ${result.threadId} via ${result.backend ?? 'unknown'}`; + const mode = result.full ? 'full' : 'visible'; + return `${result.turns.length} turns (${mode}) on ${result.threadId} via ${result.backend ?? 'unknown'}`; } if (result.delivery === 'accepted') { - return `Sent on ${result.threadId} via ${result.backend}${result.experimental ? ' (experimental)' : ''}`; + return `Sent on ${result.threadId} via ${result.backend}` + (result.conversationId ? ` (conversation ${result.conversationId})` : ''); } if (result.delivery === 'replied') { - return String(result.reply ?? 'replied'); + const id = result.conversationId ? ` [${result.conversationId}]` : ''; + return `${String(result.reply ?? 'replied')}${id}`; } if (result.delivery) return `delivery ${result.delivery}`; return JSON.stringify(result); diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index a3a2a42..6548ed9 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -7024,7 +7024,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).', + description: 'Read a ChatGPT Desktop thread via CDP. Default: visible turns. --full wheel-crawls history.', exitCode: 'result', positionals: [ 'threadId' @@ -7032,10 +7032,18 @@ var __webpack_modules__ = { inputJsonSchema: { additionalProperties: false, properties: { + full: { + default: false, + type: 'boolean' + }, limit: { default: 100, type: 'number' }, + openTimeoutMs: { + default: 90000, + type: 'number' + }, port: { type: 'number' }, @@ -7047,10 +7055,15 @@ var __webpack_modules__ = { 'threadId' ], type: 'object' + }, + render: { + maxElapsedMs: 660000 } }; const inputSchema = zod__rspack_import_2.Ikc({ - limit: zod__rspack_import_2.aig().int().min(1).max(500).default(100), + full: zod__rspack_import_2.zMY().default(false), + limit: zod__rspack_import_2.aig().int().min(1).max(2000).default(100), + openTimeoutMs: zod__rspack_import_2.aig().int().min(1).max(600000).default(90000), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), threadId: zod__rspack_import_2.YjP().min(1).max(256) }).strict(); @@ -7059,8 +7072,12 @@ var __webpack_modules__ = { const turns = Array.isArray(out.turns) ? out.turns : []; const text = turns.length > 0 ? turns.map((turn)=>{ const row = turn; - return `[${row.role ?? '?'} ${row.turnKey ?? ''}] ${row.text ?? ''}`; - }).join('\n\n') + `\n\nbackend: ${String(out.backend ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); + const body = row.userText || row.assistantText ? [ + row.userText ? `user: ${row.userText}` : null, + row.assistantText ? `assistant: ${row.assistantText}` : null + ].filter(Boolean).join('\n') : row.text ?? ''; + return `[${row.role ?? '?'} ${row.turnKey ?? ''}]\n${body}`; + }).join('\n\n') + `\n\nbackend: ${String(out.backend ?? '')} full: ${String(out.full ?? false)}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { value: out, children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { @@ -7083,7 +7100,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.', + description: 'Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .', exitCode: 'result', positionals: [ 'text' @@ -7091,9 +7108,15 @@ var __webpack_modules__ = { inputJsonSchema: { additionalProperties: false, properties: { + openTimeoutMs: { + type: 'number' + }, port: { type: 'number' }, + project: { + type: 'string' + }, text: { type: 'array', items: { @@ -7110,11 +7133,13 @@ var __webpack_modules__ = { type: 'object' }, render: { - maxElapsedMs: 120000 + maxElapsedMs: 180000 } }; const inputSchema = zod__rspack_import_2.Ikc({ + openTimeoutMs: zod__rspack_import_2.aig().int().min(1).max(600000).default(90000), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), + project: zod__rspack_import_2.YjP().min(1).max(256).optional(), text: zod__rspack_import_2.YOg(zod__rspack_import_2.YjP()).min(1), threadId: zod__rspack_import_2.YjP().min(1).max(256).optional() }).strict(); @@ -7122,7 +7147,9 @@ var __webpack_modules__ = { const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.UP)({ port: input.port, threadId: input.threadId, - text: input.text.join(' ').trim() + text: input.text.join(' ').trim(), + project: input.project, + openTimeoutMs: input.openTimeoutMs }); return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { value: out, @@ -9527,7 +9554,7 @@ var __webpack_modules__ = { })) }; } - async function appServerReadThread({ threadId, limit = 100 }) { + async function appServerReadThread({ threadId, limit = 100, full = false }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { let turns = []; @@ -9536,7 +9563,9 @@ var __webpack_modules__ = { threadId }); const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - turns = normalizeTurns(raw).slice(-limit); + turns = normalizeTurns(raw).slice(full ? 0 : -limit); + if (full && limit > 0) turns = turns.slice(0, limit); + else if (!full) turns = turns.slice(-limit); } catch { const items = await client.request('thread/items/list', { threadId, @@ -9548,7 +9577,8 @@ var __webpack_modules__ = { threadId, turns, backend: 'app-server', - limit + limit, + full }; } finally{ client.close(); @@ -9573,7 +9603,16 @@ var __webpack_modules__ = { message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined }; } - async function appServerWaitForReply({ threadId, timeoutMs = 60000 }) { + async function appServerWaitForReply({ threadId = 'unknown', timeoutMs = 60000 }) { + if (!threadId || threadId === 'unknown' || threadId === 'new') { + return { + threadId: threadId || 'unknown', + reply: '', + backend: 'app-server', + experimental: false, + delivery: 'rejected' + }; + } const baseline = await appServerReadThread({ threadId, limit: 200 @@ -9697,80 +9736,92 @@ var __webpack_modules__ = { limit }; } - async readThread({ threadId, limit = 100 }) { + async readThread({ threadId, limit = 100, full = false, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - await delay(150); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { - limit + limit, + full, + threadId }); return { threadId, turns, backend: 'cdp', - limit + limit, + full }; } - async sendMessage({ threadId, text }) { + async sendMessage({ threadId, text, project, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); + let temporaryThreadId; + let resolvedThreadId = threadId ?? 'new'; if (threadId) { - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - await delay(100); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); + } else { + await (0, _cdp_dom_js__rspack_import_2.s0)(this.#requireSession(), sessionId, { + project + }); + await delay(300); + const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + limit: 20 + }); + const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); + if (temp) { + temporaryThreadId = temp.threadId; + resolvedThreadId = temp.threadId; + } } - await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); return { - threadId: threadId ?? 'new', + threadId: resolvedThreadId, + temporaryThreadId, + project, backend: 'cdp', - experimental: true, + experimental: false, delivery: 'accepted', - message: 'Submitted via experimental CDP composer path' + sentVia, + message: 'Submitted via CDP composer (focus → insertText → Enter)' }; } - async waitForReply({ threadId, timeoutMs = 60000 }) { + async waitForReply({ threadId, timeoutMs = 120000 }) { const sessionId = await this.#ensurePageSession(); - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - const deadline = Date.now() + timeoutMs; - let previousKeys = new Set(); - let lastAssistant = ''; - let stable = 0; - const baseline = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { - limit: 500 - }); - previousKeys = new Set(baseline.map((t)=>t.turnKey)); - while(Date.now() < deadline){ - await delay(400); - const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { - limit: 500 + if (threadId && !threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && threadId !== 'new') { + try { + await this.#openAndWait(sessionId, threadId, 90000); + } catch {} + } + const baseline = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); + try { + const done = await (0, _cdp_dom_js__rspack_import_2.FG)(this.#requireSession(), sessionId, { + timeoutMs, + baselineFinalCount: baseline.finalAssistantCount }); - const fresh = turns.filter((t)=>!previousKeys.has(t.turnKey) && t.role === 'assistant'); - const candidate = fresh.at(-1)?.text ?? ''; - if (candidate && candidate === lastAssistant) { - stable += 1; - if (stable >= 3) { - return { - threadId, - reply: candidate, - backend: 'cdp', - experimental: true, - delivery: 'replied' - }; - } - } else if (candidate) { - lastAssistant = candidate; - stable = 0; - } + const resolvedId = done.conversationId || threadId || 'unknown'; + return { + threadId: resolvedId, + conversationId: done.conversationId || undefined, + reply: done.reply, + backend: 'cdp', + experimental: false, + delivery: 'replied' + }; + } catch (error) { + const last = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); + return { + threadId: last.conversationId || threadId || 'unknown', + conversationId: last.conversationId || undefined, + reply: last.reply, + backend: 'cdp', + experimental: false, + delivery: last.reply ? 'replied' : 'timeout', + ...error instanceof Error ? {} : {} + }; } - return { - threadId, - reply: lastAssistant, - backend: 'cdp', - experimental: true, - delivery: lastAssistant ? 'replied' : 'timeout' - }; } - async openThread(threadId) { + async openThread(threadId, { openTimeoutMs = 90000 } = {}) { const sessionId = await this.#ensurePageSession(); - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); return { threadId, backend: 'cdp' @@ -9818,6 +9869,12 @@ var __webpack_modules__ = { this.#session?.close(); this.#session = null; } + async #openAndWait(sessionId, threadId, openTimeoutMs) { + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { + timeoutMs: openTimeoutMs + }); + } async #attachMainWindow() { const targets = await this.listTargets(); const main = (0, _cdp_dom_js__rspack_import_2.C2)(targets); @@ -9871,32 +9928,41 @@ var __webpack_modules__ = { turnKey: 'data-turn-key', userBubble: 'data-user-message-bubble', timelineScroll: 'data-app-action-timeline-scroll', - virtualizedTurn: 'data-virtualized-turn-content' + virtualizedTurn: 'data-virtualized-turn-content', + composer: 'data-codex-composer', + finalAssistant: 'data-local-conversation-final-assistant', + markdownTextStyle: 'data-markdown-text-style', + conversationAnnotation: 'data-response-annotation-conversation' }; const MAIN_CONTENT_SURFACE_CLASS_PREFIX = '_MainContentSurface'; - const COMPOSER_SELECTORS = [ - 'main [contenteditable="true"]', - 'main textarea', - '[data-app-action-composer] [contenteditable="true"]', - '[data-app-action-composer] textarea', - 'form [contenteditable="true"]', - 'form textarea' - ]; - const SEND_BUTTON_SELECTORS = [ - 'button[data-app-action-send]', - 'button[aria-label="Send"]', - 'button[aria-label="Send message"]', - 'main button[type="submit"]' - ]; + const HISTORY_GAP_PREFIX = 'history-gap:'; + const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; + const LOADING_TASK_TEXT = 'Loading task…'; + const DEFAULT_OPEN_TIMEOUT_MS = 90000; + const DEFAULT_FULL_READ_IDLE_WHEELS = 8; + const DEFAULT_FULL_READ_MAX_WHEELS = 400; + const COMPOSER_SELECTOR = `[${ATTR.composer}="true"][contenteditable="true"]`; + const SEND_BUTTON_SELECTOR = 'button[aria-label="Send"]'; + const STOP_BUTTON_SELECTOR = 'main button[aria-label="Stop"]'; + const FINAL_ASSISTANT_SELECTOR = `[${ATTR.finalAssistant}="true"]`; + const ASSISTANT_MESSAGE_SELECTOR = `[${ATTR.finalAssistant}="true"] [${ATTR.markdownTextStyle}="assistant-message"]`; + const CONVERSATION_ANNOTATION_SELECTOR = `[${ATTR.conversationAnnotation}]`; const SELECTORS = { threadRow: `[role="button"][${ATTR.threadRow}]`, turn: `[${ATTR.turnKey}]`, userBubble: `[${ATTR.userBubble}]`, timelineScroll: `[${ATTR.timelineScroll}]`, - mainSurface: 'main', - composerCandidates: COMPOSER_SELECTORS, - sendButtonCandidates: SEND_BUTTON_SELECTORS + composer: COMPOSER_SELECTOR, + sendButton: SEND_BUTTON_SELECTOR, + stopButton: STOP_BUTTON_SELECTOR, + finalAssistant: FINAL_ASSISTANT_SELECTOR, + assistantMessage: ASSISTANT_MESSAGE_SELECTOR, + conversationAnnotation: CONVERSATION_ANNOTATION_SELECTOR, + newChatFallback: 'button' }; + function newChatInProjectSelector(project) { + return `button[aria-label=${JSON.stringify(`Start new chat in ${project}`)}]`; + } function isMainWindowTarget(target) { if (target.type !== 'page') return false; const url = typeof target.url === 'string' ? target.url : ''; @@ -9915,15 +9981,33 @@ var __webpack_modules__ = { function pickMainWindowTarget(targets) { return targets.find((t)=>isMainWindowTarget(t)) ?? null; } + function dedupeThreadsById(threads) { + const seen = new Set(); + const out = []; + for (const thread of threads){ + if (!thread.threadId || seen.has(thread.threadId)) continue; + seen.add(thread.threadId); + out.push(thread); + } + return out; + } const LIST_THREADS_EXPRESSION = `(() => { const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); - return rows.map((row) => ({ - threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || '', - title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), - pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', - selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', - kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', - })).filter((t) => t.threadId); + const seen = new Set(); + const out = []; + for (const row of rows) { + const threadId = row.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''; + if (!threadId || seen.has(threadId)) continue; + seen.add(threadId); + out.push({ + threadId, + title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), + pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', + selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', + kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + }); + } + return out; })()`; function openThreadExpression(threadId) { return `(() => { @@ -9935,7 +10019,69 @@ var __webpack_modules__ = { return { ok: true, threadId: id }; })()`; } - const READ_THREAD_EXPRESSION = `(() => { + function startNewChatExpression(project) { + const projectSel = project ? newChatInProjectSelector(project) : null; + return `(() => { + const projectSel = ${JSON.stringify(projectSel)}; + if (projectSel) { + const preferred = document.querySelector(projectSel); + if (preferred) { + preferred.click(); + return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; + } + } + const buttons = Array.from(document.querySelectorAll('button')); + const fallback = buttons.find((btn) => (btn.textContent || '').trim() === 'New chat'); + if (!fallback) return { ok: false, error: 'new-chat-not-found' }; + fallback.click(); + return { ok: true, via: 'fallback' }; + })()`; + } + const LOADING_TASK_GONE_EXPRESSION = `(() => { + const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; + const mains = Array.from(document.querySelectorAll('main')); + const surface = + mains.find((el) => typeof el.className === 'string' && el.className.includes(surfacePrefix)) + || (mains.length >= 2 ? mains[1] : null) + || mains[0] + || document.body; + const text = (surface.innerText || '').replace(/\\u2026/g, '…'); + return !text.includes(${JSON.stringify(LOADING_TASK_TEXT)}); +})()`; + const FOCUS_COMPOSER_EXPRESSION = `(() => { + const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.focus(); + return { ok: true }; +})()`; + const REPLY_STATE_EXPRESSION = `(() => { + const stop = document.querySelector(${JSON.stringify(STOP_BUTTON_SELECTOR)}); + const finals = Array.from(document.querySelectorAll(${JSON.stringify(FINAL_ASSISTANT_SELECTOR)})); + const lastFinal = finals.at(-1) || null; + const annotation = lastFinal + ? lastFinal.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}) + || lastFinal.closest(${JSON.stringify(SELECTORS.turn)})?.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}) + : document.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}); + const conversationId = annotation + ? (annotation.getAttribute(${JSON.stringify(ATTR.conversationAnnotation)}) || '') + : ''; + const messageEl = lastFinal + ? lastFinal.querySelector(${JSON.stringify(`[${ATTR.markdownTextStyle}="assistant-message"]`)}) + : null; + const reply = messageEl ? (messageEl.innerText || '').trim() : ''; + const turns = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.turn)})); + const lastTurn = turns.at(-1); + const lastTurnKey = lastTurn ? (lastTurn.getAttribute(${JSON.stringify(ATTR.turnKey)}) || '') : ''; + return { + stopVisible: Boolean(stop), + finalAssistantCount: finals.length, + conversationId, + reply, + lastTurnKey, + }; +})()`; + const HARVEST_VISIBLE_TURNS_EXPRESSION = `(() => { + const gapPrefix = ${JSON.stringify(HISTORY_GAP_PREFIX)}; const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); const surface = @@ -9947,114 +10093,51 @@ var __webpack_modules__ = { surface.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}) || document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); const root = scroll || surface; - const collected = new Map(); - const statusRe = /^Worked for \\d+s$/i; - const harvest = () => { - for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { - const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; - if (!turnKey || collected.has(turnKey)) continue; - const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); - const text = (el.innerText || '').trim(); - let role = 'assistant'; - if (user) role = 'user'; - else if (!text || statusRe.test(text)) role = 'status'; - collected.set(turnKey, { turnKey, role, text }); - } - }; - const maxPasses = 80; - let stable = 0; - let lastSize = -1; - if (scroll) scroll.scrollTop = 0; - for (let i = 0; i < maxPasses; i++) { - harvest(); - if (collected.size === lastSize) { - stable += 1; - if (stable >= 3) break; - } else { - stable = 0; - lastSize = collected.size; - } - if (scroll) { - const next = Math.min(scroll.scrollHeight, scroll.scrollTop + Math.max(scroll.clientHeight, 200)); - if (next <= scroll.scrollTop && stable >= 1) break; - scroll.scrollTop = next; - } else { - break; + const out = []; + for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { + const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; + if (!turnKey || turnKey.startsWith(gapPrefix)) continue; + const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); + const assistant = el.querySelector(${JSON.stringify(ASSISTANT_MESSAGE_SELECTOR)}); + const userText = user ? (user.innerText || '').trim() : ''; + const assistantText = assistant ? (assistant.innerText || '').trim() : ''; + const raw = (el.innerText || '').trim(); + const statusRe = /^Worked for \\d+s$/i; + let role = 'assistant'; + let text = assistantText || userText || raw; + if (user && !assistantText) { + role = 'user'; + text = userText || raw; + } else if (assistantText) { + role = 'assistant'; + text = assistantText; + } else if (!raw || statusRe.test(raw)) { + role = 'status'; + text = raw; } + out.push({ turnKey, role, text, userText, assistantText }); } - harvest(); - return Array.from(collected.values()); + return out; })()`; - const FOCUS_COMPOSER_EXPRESSION = `(() => { - const composers = ${JSON.stringify([ - ...COMPOSER_SELECTORS - ])}; - for (const sel of composers) { - const composer = document.querySelector(sel); - if (!composer) continue; - composer.focus(); - return { ok: true, selector: sel, contentEditable: !!composer.isContentEditable }; - } - return { ok: false, error: 'composer-not-found' }; -})()`; - function fillComposerExpression(text) { - return `(() => { - const text = ${JSON.stringify(text)}; - const composers = ${JSON.stringify([ - ...COMPOSER_SELECTORS - ])}; - let composer = null; - for (const sel of composers) { - composer = document.querySelector(sel); - if (composer) break; - } - if (!composer) return { ok: false, error: 'composer-not-found' }; - composer.focus(); - if (composer.isContentEditable) { - composer.textContent = text; - composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: text, inputType: 'insertText' })); - } else if ('value' in composer) { - composer.value = text; - composer.dispatchEvent(new Event('input', { bubbles: true })); - } else { - return { ok: false, error: 'composer-unsupported' }; - } - return { ok: true }; - })()`; - } - const SUBMIT_COMPOSER_EXPRESSION = `(() => { - const buttons = ${JSON.stringify([ - ...SEND_BUTTON_SELECTORS - ])}; - for (const sel of buttons) { - const btn = document.querySelector(sel); - if (btn && !btn.disabled) { - btn.click(); - return { ok: true, sentVia: 'button', selector: sel }; - } - } - const composers = ${JSON.stringify([ - ...COMPOSER_SELECTORS - ])}; - let composer = null; - for (const sel of composers) { - composer = document.querySelector(sel); - if (composer) break; - } - if (!composer) return { ok: false, error: 'composer-not-found' }; - composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); - composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); - return { ok: true, sentVia: 'enter' }; + const TIMELINE_SCROLL_METRICS_EXPRESSION = `(() => { + const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + if (!scroll) return { ok: false }; + const rect = scroll.getBoundingClientRect(); + return { + ok: true, + x: Math.floor(rect.left + rect.width / 2), + y: Math.floor(rect.top + Math.min(rect.height / 2, 120)), + scrollTop: scroll.scrollTop, + scrollHeight: scroll.scrollHeight, + clientHeight: scroll.clientHeight, + }; })()`; - function sendMessageExpression(text) { - return fillComposerExpression(text); - } async function listThreadsFromDom(session, sessionId, { limit = 50 } = {}) { const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { sessionId }); if (!Array.isArray(rows)) return []; - return rows.slice(0, limit).map((row)=>({ + return dedupeThreadsById(rows).slice(0, limit).map((row)=>({ threadId: String(row.threadId), title: String(row.title ?? ''), pinned: Boolean(row.pinned), @@ -10070,60 +10153,213 @@ var __webpack_modules__ = { throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); } } - async function readTurnsFromDom(session, sessionId, { limit = 100 } = {}) { - const turns = await session.evaluate(READ_THREAD_EXPRESSION, { + async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS } = {}) { + const deadline = Date.now() + timeoutMs; + while(Date.now() < deadline){ + const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { + sessionId + }); + if (gone) return; + await delay(250); + } + throw new Error(`ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); + } + async function startNewChatInDom(session, sessionId, { project } = {}) { + const result = await session.evaluate(startNewChatExpression(project), { sessionId }); - if (!Array.isArray(turns)) return []; - return turns.slice(-limit).map((turn)=>({ - turnKey: String(turn.turnKey), - role: turn.role === 'user' || turn.role === 'status' ? turn.role : 'assistant', - text: String(turn.text ?? '') - })); + if (!result?.ok) { + throw new Error(project ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` : 'ChatGPT Desktop "New chat" button not found'); + } + return { + via: result.via ?? 'unknown' + }; } - async function sendMessageInDom(session, sessionId, text) { + async function focusComposer(session, sessionId) { const focused = await session.evaluate(FOCUS_COMPOSER_EXPRESSION, { sessionId }); if (!focused?.ok) { - throw new Error('ChatGPT Desktop composer not found (experimental send path)'); - } - let inserted = false; - try { - await session.send('Input.insertText', { - text - }, { - sessionId - }); - inserted = true; - } catch { - inserted = false; + throw new Error('ChatGPT Desktop composer not found ([data-codex-composer=true])'); } - if (!inserted) { - const filled = await session.evaluate(fillComposerExpression(text), { - sessionId - }); - if (!filled?.ok) { - throw new Error(filled?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${filled?.error ?? 'fill-failed'}`); - } + } + async function submitComposerWithEnter(session, sessionId) { + const base = { + windowsVirtualKeyCode: 13, + code: 'Enter', + key: 'Enter', + text: '\r', + unmodifiedText: '\r' + }; + await session.send('Input.dispatchKeyEvent', { + type: 'rawKeyDown', + ...base + }, { + sessionId + }); + await session.send('Input.dispatchKeyEvent', { + type: 'char', + ...base + }, { + sessionId + }); + await session.send('Input.dispatchKeyEvent', { + type: 'keyUp', + ...base + }, { + sessionId + }); + } + async function submitComposerWithButton(session, sessionId) { + const result = await session.evaluate(`(() => { + const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); + if (!btn || btn.disabled) return { ok: false }; + btn.click(); + return { ok: true }; + })()`, { + sessionId + }); + return Boolean(result?.ok); + } + async function sendMessageInDom(session, sessionId, text) { + await focusComposer(session, sessionId); + await session.send('Input.insertText', { + text + }, { + sessionId + }); + await submitComposerWithEnter(session, sessionId); + const sendStillVisible = await session.evaluate(`(() => { + const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); + return Boolean(btn && !btn.disabled); + })()`, { + sessionId + }); + if (sendStillVisible) { + const clicked = await submitComposerWithButton(session, sessionId); + if (clicked) return { + sentVia: 'button' + }; } - const submitted = await session.evaluate(SUBMIT_COMPOSER_EXPRESSION, { + return { + sentVia: 'enter' + }; + } + async function readReplyState(session, sessionId) { + const state = await session.evaluate(REPLY_STATE_EXPRESSION, { sessionId }); - if (!submitted?.ok) { - throw new Error(`ChatGPT Desktop send submit failed: ${submitted?.error ?? 'unknown'}`); + return { + stopVisible: Boolean(state?.stopVisible), + finalAssistantCount: Number(state?.finalAssistantCount ?? 0), + conversationId: String(state?.conversationId ?? ''), + reply: String(state?.reply ?? ''), + lastTurnKey: String(state?.lastTurnKey ?? '') + }; + } + async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0 } = {}) { + const deadline = Date.now() + timeoutMs; + let sawStop = false; + const started = Date.now(); + while(Date.now() < deadline){ + const state = await readReplyState(session, sessionId); + if (state.stopVisible) sawStop = true; + const hasNewFinal = state.finalAssistantCount > baselineFinalCount && Boolean(state.reply); + if (!state.stopVisible && hasNewFinal && (sawStop || Date.now() - started > 1500)) { + return { + reply: state.reply, + conversationId: state.conversationId + }; + } + await delay(200); + } + const last = await readReplyState(session, sessionId); + if (!last.stopVisible && last.finalAssistantCount > baselineFinalCount && last.reply) { + return { + reply: last.reply, + conversationId: last.conversationId + }; } + throw new Error(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); + } + function normalizeTurn(raw) { + const role = raw.role === 'user' || raw.role === 'status' || raw.role === 'assistant' ? raw.role : raw.assistantText ? 'assistant' : raw.userText ? 'user' : 'assistant'; return { - sentVia: submitted.sentVia ?? (inserted ? 'insertText' : 'dom') + turnKey: String(raw.turnKey ?? ''), + role, + text: String(raw.text ?? raw.assistantText ?? raw.userText ?? ''), + userText: raw.userText ? String(raw.userText) : undefined, + assistantText: raw.assistantText ? String(raw.assistantText) : undefined }; } + async function harvestVisibleTurns(session, sessionId) { + const rows = await session.evaluate(HARVEST_VISIBLE_TURNS_EXPRESSION, { + sessionId + }); + if (!Array.isArray(rows)) return []; + return rows.map(normalizeTurn).filter((t)=>t.turnKey && !t.turnKey.startsWith(HISTORY_GAP_PREFIX)); + } + async function readTurnsFromDom(session, sessionId, { limit = 100, full = false, threadId, idleWheels = DEFAULT_FULL_READ_IDLE_WHEELS, maxWheels = DEFAULT_FULL_READ_MAX_WHEELS } = {}) { + const collected = new Map(); + const ingest = async ()=>{ + for (const turn of (await harvestVisibleTurns(session, sessionId))){ + collected.set(turn.turnKey, turn); + } + }; + await ingest(); + if (!full) { + const visible = [ + ...collected.values() + ]; + return limit > 0 ? visible.slice(-limit) : visible; + } + let idle = 0; + for(let step = 0; step < maxWheels; step++){ + const before = collected.size; + const metrics = await session.evaluate(TIMELINE_SCROLL_METRICS_EXPRESSION, { + sessionId + }); + if (!metrics?.ok || metrics.x == null || metrics.y == null) break; + await session.send('Input.dispatchMouseEvent', { + type: 'mouseWheel', + x: metrics.x, + y: metrics.y, + deltaX: 0, + deltaY: -800 + }, { + sessionId + }); + await delay(120); + await ingest(); + if (collected.size === before) { + idle += 1; + if (idle >= idleWheels) break; + } else { + idle = 0; + } + if (threadId && collected.has(threadId)) break; + } + const all = [ + ...collected.values() + ]; + return limit > 0 ? all.slice(0, limit) : all; + } + function delay(ms) { + return new Promise((resolve)=>setTimeout(resolve, ms)); + } __webpack_require__.d(__webpack_exports__, { AY: ()=>listThreadsFromDom, C2: ()=>pickMainWindowTarget, + FG: ()=>waitForReplyDone, JU: ()=>readTurnsFromDom, Kl: ()=>openThreadInDom, Mr: ()=>summarizeTargetInfos, - lh: ()=>sendMessageInDom + YX: ()=>readReplyState, + Zx: ()=>waitForLoadingTaskGone, + lh: ()=>sendMessageInDom, + s0: ()=>startNewChatInDom + }, { + hA: TEMP_THREAD_ID_PREFIX }); }, "./src/core/chatgpt-desktop/cdp-session.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -10389,13 +10625,16 @@ var __webpack_modules__ = { return await this.#cdp.waitForReply(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return this.#fallbacks.waitForReply(options); + return this.#fallbacks.waitForReply({ + threadId: options.threadId ?? 'unknown', + timeoutMs: options.timeoutMs + }); } } - async openThread(threadId) { + async openThread(threadId, options) { try { await this.#ensureCdp(); - return await this.#cdp.openThread(threadId); + return await this.#cdp.openThread(threadId, options); } catch (error) { if (!isCdpFailure(error)) throw error; return this.#fallbacks.openThread(threadId); @@ -10532,17 +10771,21 @@ var __webpack_modules__ = { const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, - limit: zod__rspack_import_4.aig().int().min(1).max(500).default(100) + limit: zod__rspack_import_4.aig().int().min(1).max(2000).default(100), + full: zod__rspack_import_4.zMY().default(false), + openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); const sendSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), - text: zod__rspack_import_4.YjP().min(1).max(100000) + text: zod__rspack_import_4.YjP().min(1).max(100000), + project: zod__rspack_import_4.YjP().min(1).max(256).optional(), + openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); const waitReplySchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), - threadId, - timeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(60000) + threadId: threadId.optional(), + timeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(120000) }).strict(); const resultSchema = zod__rspack_import_4.Ikc({ exitCode: zod__rspack_import_4.KCZ([ @@ -10561,7 +10804,8 @@ var __webpack_modules__ = { return run(adapter); } function asResult(value) { - return resultSchema.parse(value); + const cleaned = Object.fromEntries(Object.entries(value).filter(([, entry])=>entry !== undefined)); + return resultSchema.parse(cleaned); } function mapError(error) { if (error instanceof _errors_js__rspack_import_1.EH) { @@ -10607,7 +10851,9 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ threadId: input.threadId, - limit: input.limit + limit: input.limit, + full: input.full, + openTimeoutMs: input.openTimeoutMs })); return asResult({ ...out, @@ -10621,7 +10867,9 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.sendMessage({ threadId: input.threadId, - text: input.text + text: input.text, + project: input.project, + openTimeoutMs: input.openTimeoutMs })); return asResult({ ...out, @@ -10656,13 +10904,15 @@ var __webpack_modules__ = { return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { - return `${result.turns.length} turns on ${result.threadId} via ${result.backend ?? 'unknown'}`; + const mode = result.full ? 'full' : 'visible'; + return `${result.turns.length} turns (${mode}) on ${result.threadId} via ${result.backend ?? 'unknown'}`; } if (result.delivery === 'accepted') { - return `Sent on ${result.threadId} via ${result.backend}${result.experimental ? ' (experimental)' : ''}`; + return `Sent on ${result.threadId} via ${result.backend}` + (result.conversationId ? ` (conversation ${result.conversationId})` : ''); } if (result.delivery === 'replied') { - return String(result.reply ?? 'replied'); + const id = result.conversationId ? ` [${result.conversationId}]` : ''; + return `${String(result.reply ?? 'replied')}${id}`; } if (result.delivery) return `delivery ${result.delivery}`; return JSON.stringify(result); @@ -38897,9 +39147,17 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).", + "description": "Read a ChatGPT Desktop thread via CDP. Default: visible turns. --full wheel-crawls history.", "exitCode": "result", "options": [ + { + "defaultValue": false, + "key": "full", + "kind": "boolean", + "option": "full", + "repeated": false, + "required": false + }, { "defaultValue": 100, "key": "limit", @@ -38908,6 +39166,14 @@ var __webpack_modules__ = { "repeated": false, "required": false }, + { + "defaultValue": 90000, + "key": "openTimeoutMs", + "kind": "number", + "option": "open-timeout-ms", + "repeated": false, + "required": false + }, { "key": "port", "kind": "number", @@ -38928,14 +39194,24 @@ var __webpack_modules__ = { "chatgpt-desktop", "read" ], + "render": { + "maxElapsedMs": 660000 + }, "rendered": true, "routeId": "cli:chatgpt-desktop/read" }, { "aliases": [], - "description": "EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.", + "description": "Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .", "exitCode": "result", "options": [ + { + "key": "openTimeoutMs", + "kind": "number", + "option": "open-timeout-ms", + "repeated": false, + "required": false + }, { "key": "port", "kind": "number", @@ -38943,6 +39219,13 @@ var __webpack_modules__ = { "repeated": false, "required": false }, + { + "key": "project", + "kind": "string", + "option": "project", + "repeated": false, + "required": false + }, { "key": "text", "kind": "string", @@ -38964,7 +39247,7 @@ var __webpack_modules__ = { "send" ], "render": { - "maxElapsedMs": 120000 + "maxElapsedMs": 180000 }, "rendered": true, "routeId": "cli:chatgpt-desktop/send" diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index fcf9a25..a001f21 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8102,7 +8102,7 @@ var __webpack_modules__ = { })) }; } - async function appServerReadThread({ threadId, limit = 100 }) { + async function appServerReadThread({ threadId, limit = 100, full = false }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { let turns = []; @@ -8111,7 +8111,9 @@ var __webpack_modules__ = { threadId }); const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - turns = normalizeTurns(raw).slice(-limit); + turns = normalizeTurns(raw).slice(full ? 0 : -limit); + if (full && limit > 0) turns = turns.slice(0, limit); + else if (!full) turns = turns.slice(-limit); } catch { const items = await client.request('thread/items/list', { threadId, @@ -8123,7 +8125,8 @@ var __webpack_modules__ = { threadId, turns, backend: 'app-server', - limit + limit, + full }; } finally{ client.close(); @@ -8148,7 +8151,16 @@ var __webpack_modules__ = { message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined }; } - async function appServerWaitForReply({ threadId, timeoutMs = 60000 }) { + async function appServerWaitForReply({ threadId = 'unknown', timeoutMs = 60000 }) { + if (!threadId || threadId === 'unknown' || threadId === 'new') { + return { + threadId: threadId || 'unknown', + reply: '', + backend: 'app-server', + experimental: false, + delivery: 'rejected' + }; + } const baseline = await appServerReadThread({ threadId, limit: 200 @@ -8272,80 +8284,92 @@ var __webpack_modules__ = { limit }; } - async readThread({ threadId, limit = 100 }) { + async readThread({ threadId, limit = 100, full = false, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - await delay(150); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { - limit + limit, + full, + threadId }); return { threadId, turns, backend: 'cdp', - limit + limit, + full }; } - async sendMessage({ threadId, text }) { + async sendMessage({ threadId, text, project, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); + let temporaryThreadId; + let resolvedThreadId = threadId ?? 'new'; if (threadId) { - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - await delay(100); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); + } else { + await (0, _cdp_dom_js__rspack_import_2.s0)(this.#requireSession(), sessionId, { + project + }); + await delay(300); + const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + limit: 20 + }); + const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); + if (temp) { + temporaryThreadId = temp.threadId; + resolvedThreadId = temp.threadId; + } } - await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); return { - threadId: threadId ?? 'new', + threadId: resolvedThreadId, + temporaryThreadId, + project, backend: 'cdp', - experimental: true, + experimental: false, delivery: 'accepted', - message: 'Submitted via experimental CDP composer path' + sentVia, + message: 'Submitted via CDP composer (focus → insertText → Enter)' }; } - async waitForReply({ threadId, timeoutMs = 60000 }) { + async waitForReply({ threadId, timeoutMs = 120000 }) { const sessionId = await this.#ensurePageSession(); - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - const deadline = Date.now() + timeoutMs; - let previousKeys = new Set(); - let lastAssistant = ''; - let stable = 0; - const baseline = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { - limit: 500 - }); - previousKeys = new Set(baseline.map((t)=>t.turnKey)); - while(Date.now() < deadline){ - await delay(400); - const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { - limit: 500 + if (threadId && !threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && threadId !== 'new') { + try { + await this.#openAndWait(sessionId, threadId, 90000); + } catch {} + } + const baseline = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); + try { + const done = await (0, _cdp_dom_js__rspack_import_2.FG)(this.#requireSession(), sessionId, { + timeoutMs, + baselineFinalCount: baseline.finalAssistantCount }); - const fresh = turns.filter((t)=>!previousKeys.has(t.turnKey) && t.role === 'assistant'); - const candidate = fresh.at(-1)?.text ?? ''; - if (candidate && candidate === lastAssistant) { - stable += 1; - if (stable >= 3) { - return { - threadId, - reply: candidate, - backend: 'cdp', - experimental: true, - delivery: 'replied' - }; - } - } else if (candidate) { - lastAssistant = candidate; - stable = 0; - } + const resolvedId = done.conversationId || threadId || 'unknown'; + return { + threadId: resolvedId, + conversationId: done.conversationId || undefined, + reply: done.reply, + backend: 'cdp', + experimental: false, + delivery: 'replied' + }; + } catch (error) { + const last = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); + return { + threadId: last.conversationId || threadId || 'unknown', + conversationId: last.conversationId || undefined, + reply: last.reply, + backend: 'cdp', + experimental: false, + delivery: last.reply ? 'replied' : 'timeout', + ...error instanceof Error ? {} : {} + }; } - return { - threadId, - reply: lastAssistant, - backend: 'cdp', - experimental: true, - delivery: lastAssistant ? 'replied' : 'timeout' - }; } - async openThread(threadId) { + async openThread(threadId, { openTimeoutMs = 90000 } = {}) { const sessionId = await this.#ensurePageSession(); - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); return { threadId, backend: 'cdp' @@ -8393,6 +8417,12 @@ var __webpack_modules__ = { this.#session?.close(); this.#session = null; } + async #openAndWait(sessionId, threadId, openTimeoutMs) { + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { + timeoutMs: openTimeoutMs + }); + } async #attachMainWindow() { const targets = await this.listTargets(); const main = (0, _cdp_dom_js__rspack_import_2.C2)(targets); @@ -8446,32 +8476,41 @@ var __webpack_modules__ = { turnKey: 'data-turn-key', userBubble: 'data-user-message-bubble', timelineScroll: 'data-app-action-timeline-scroll', - virtualizedTurn: 'data-virtualized-turn-content' + virtualizedTurn: 'data-virtualized-turn-content', + composer: 'data-codex-composer', + finalAssistant: 'data-local-conversation-final-assistant', + markdownTextStyle: 'data-markdown-text-style', + conversationAnnotation: 'data-response-annotation-conversation' }; const MAIN_CONTENT_SURFACE_CLASS_PREFIX = '_MainContentSurface'; - const COMPOSER_SELECTORS = [ - 'main [contenteditable="true"]', - 'main textarea', - '[data-app-action-composer] [contenteditable="true"]', - '[data-app-action-composer] textarea', - 'form [contenteditable="true"]', - 'form textarea' - ]; - const SEND_BUTTON_SELECTORS = [ - 'button[data-app-action-send]', - 'button[aria-label="Send"]', - 'button[aria-label="Send message"]', - 'main button[type="submit"]' - ]; + const HISTORY_GAP_PREFIX = 'history-gap:'; + const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; + const LOADING_TASK_TEXT = 'Loading task…'; + const DEFAULT_OPEN_TIMEOUT_MS = 90000; + const DEFAULT_FULL_READ_IDLE_WHEELS = 8; + const DEFAULT_FULL_READ_MAX_WHEELS = 400; + const COMPOSER_SELECTOR = `[${ATTR.composer}="true"][contenteditable="true"]`; + const SEND_BUTTON_SELECTOR = 'button[aria-label="Send"]'; + const STOP_BUTTON_SELECTOR = 'main button[aria-label="Stop"]'; + const FINAL_ASSISTANT_SELECTOR = `[${ATTR.finalAssistant}="true"]`; + const ASSISTANT_MESSAGE_SELECTOR = `[${ATTR.finalAssistant}="true"] [${ATTR.markdownTextStyle}="assistant-message"]`; + const CONVERSATION_ANNOTATION_SELECTOR = `[${ATTR.conversationAnnotation}]`; const SELECTORS = { threadRow: `[role="button"][${ATTR.threadRow}]`, turn: `[${ATTR.turnKey}]`, userBubble: `[${ATTR.userBubble}]`, timelineScroll: `[${ATTR.timelineScroll}]`, - mainSurface: 'main', - composerCandidates: COMPOSER_SELECTORS, - sendButtonCandidates: SEND_BUTTON_SELECTORS + composer: COMPOSER_SELECTOR, + sendButton: SEND_BUTTON_SELECTOR, + stopButton: STOP_BUTTON_SELECTOR, + finalAssistant: FINAL_ASSISTANT_SELECTOR, + assistantMessage: ASSISTANT_MESSAGE_SELECTOR, + conversationAnnotation: CONVERSATION_ANNOTATION_SELECTOR, + newChatFallback: 'button' }; + function newChatInProjectSelector(project) { + return `button[aria-label=${JSON.stringify(`Start new chat in ${project}`)}]`; + } function isMainWindowTarget(target) { if (target.type !== 'page') return false; const url = typeof target.url === 'string' ? target.url : ''; @@ -8490,15 +8529,33 @@ var __webpack_modules__ = { function pickMainWindowTarget(targets) { return targets.find((t)=>isMainWindowTarget(t)) ?? null; } + function dedupeThreadsById(threads) { + const seen = new Set(); + const out = []; + for (const thread of threads){ + if (!thread.threadId || seen.has(thread.threadId)) continue; + seen.add(thread.threadId); + out.push(thread); + } + return out; + } const LIST_THREADS_EXPRESSION = `(() => { const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); - return rows.map((row) => ({ - threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || '', - title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), - pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', - selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', - kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', - })).filter((t) => t.threadId); + const seen = new Set(); + const out = []; + for (const row of rows) { + const threadId = row.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''; + if (!threadId || seen.has(threadId)) continue; + seen.add(threadId); + out.push({ + threadId, + title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), + pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', + selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', + kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + }); + } + return out; })()`; function openThreadExpression(threadId) { return `(() => { @@ -8510,7 +8567,69 @@ var __webpack_modules__ = { return { ok: true, threadId: id }; })()`; } - const READ_THREAD_EXPRESSION = `(() => { + function startNewChatExpression(project) { + const projectSel = project ? newChatInProjectSelector(project) : null; + return `(() => { + const projectSel = ${JSON.stringify(projectSel)}; + if (projectSel) { + const preferred = document.querySelector(projectSel); + if (preferred) { + preferred.click(); + return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; + } + } + const buttons = Array.from(document.querySelectorAll('button')); + const fallback = buttons.find((btn) => (btn.textContent || '').trim() === 'New chat'); + if (!fallback) return { ok: false, error: 'new-chat-not-found' }; + fallback.click(); + return { ok: true, via: 'fallback' }; + })()`; + } + const LOADING_TASK_GONE_EXPRESSION = `(() => { + const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; + const mains = Array.from(document.querySelectorAll('main')); + const surface = + mains.find((el) => typeof el.className === 'string' && el.className.includes(surfacePrefix)) + || (mains.length >= 2 ? mains[1] : null) + || mains[0] + || document.body; + const text = (surface.innerText || '').replace(/\\u2026/g, '…'); + return !text.includes(${JSON.stringify(LOADING_TASK_TEXT)}); +})()`; + const FOCUS_COMPOSER_EXPRESSION = `(() => { + const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.focus(); + return { ok: true }; +})()`; + const REPLY_STATE_EXPRESSION = `(() => { + const stop = document.querySelector(${JSON.stringify(STOP_BUTTON_SELECTOR)}); + const finals = Array.from(document.querySelectorAll(${JSON.stringify(FINAL_ASSISTANT_SELECTOR)})); + const lastFinal = finals.at(-1) || null; + const annotation = lastFinal + ? lastFinal.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}) + || lastFinal.closest(${JSON.stringify(SELECTORS.turn)})?.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}) + : document.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}); + const conversationId = annotation + ? (annotation.getAttribute(${JSON.stringify(ATTR.conversationAnnotation)}) || '') + : ''; + const messageEl = lastFinal + ? lastFinal.querySelector(${JSON.stringify(`[${ATTR.markdownTextStyle}="assistant-message"]`)}) + : null; + const reply = messageEl ? (messageEl.innerText || '').trim() : ''; + const turns = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.turn)})); + const lastTurn = turns.at(-1); + const lastTurnKey = lastTurn ? (lastTurn.getAttribute(${JSON.stringify(ATTR.turnKey)}) || '') : ''; + return { + stopVisible: Boolean(stop), + finalAssistantCount: finals.length, + conversationId, + reply, + lastTurnKey, + }; +})()`; + const HARVEST_VISIBLE_TURNS_EXPRESSION = `(() => { + const gapPrefix = ${JSON.stringify(HISTORY_GAP_PREFIX)}; const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); const surface = @@ -8522,114 +8641,51 @@ var __webpack_modules__ = { surface.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}) || document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); const root = scroll || surface; - const collected = new Map(); - const statusRe = /^Worked for \\d+s$/i; - const harvest = () => { - for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { - const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; - if (!turnKey || collected.has(turnKey)) continue; - const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); - const text = (el.innerText || '').trim(); - let role = 'assistant'; - if (user) role = 'user'; - else if (!text || statusRe.test(text)) role = 'status'; - collected.set(turnKey, { turnKey, role, text }); - } - }; - const maxPasses = 80; - let stable = 0; - let lastSize = -1; - if (scroll) scroll.scrollTop = 0; - for (let i = 0; i < maxPasses; i++) { - harvest(); - if (collected.size === lastSize) { - stable += 1; - if (stable >= 3) break; - } else { - stable = 0; - lastSize = collected.size; - } - if (scroll) { - const next = Math.min(scroll.scrollHeight, scroll.scrollTop + Math.max(scroll.clientHeight, 200)); - if (next <= scroll.scrollTop && stable >= 1) break; - scroll.scrollTop = next; - } else { - break; + const out = []; + for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { + const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; + if (!turnKey || turnKey.startsWith(gapPrefix)) continue; + const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); + const assistant = el.querySelector(${JSON.stringify(ASSISTANT_MESSAGE_SELECTOR)}); + const userText = user ? (user.innerText || '').trim() : ''; + const assistantText = assistant ? (assistant.innerText || '').trim() : ''; + const raw = (el.innerText || '').trim(); + const statusRe = /^Worked for \\d+s$/i; + let role = 'assistant'; + let text = assistantText || userText || raw; + if (user && !assistantText) { + role = 'user'; + text = userText || raw; + } else if (assistantText) { + role = 'assistant'; + text = assistantText; + } else if (!raw || statusRe.test(raw)) { + role = 'status'; + text = raw; } + out.push({ turnKey, role, text, userText, assistantText }); } - harvest(); - return Array.from(collected.values()); + return out; })()`; - const FOCUS_COMPOSER_EXPRESSION = `(() => { - const composers = ${JSON.stringify([ - ...COMPOSER_SELECTORS - ])}; - for (const sel of composers) { - const composer = document.querySelector(sel); - if (!composer) continue; - composer.focus(); - return { ok: true, selector: sel, contentEditable: !!composer.isContentEditable }; - } - return { ok: false, error: 'composer-not-found' }; -})()`; - function fillComposerExpression(text) { - return `(() => { - const text = ${JSON.stringify(text)}; - const composers = ${JSON.stringify([ - ...COMPOSER_SELECTORS - ])}; - let composer = null; - for (const sel of composers) { - composer = document.querySelector(sel); - if (composer) break; - } - if (!composer) return { ok: false, error: 'composer-not-found' }; - composer.focus(); - if (composer.isContentEditable) { - composer.textContent = text; - composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: text, inputType: 'insertText' })); - } else if ('value' in composer) { - composer.value = text; - composer.dispatchEvent(new Event('input', { bubbles: true })); - } else { - return { ok: false, error: 'composer-unsupported' }; - } - return { ok: true }; - })()`; - } - const SUBMIT_COMPOSER_EXPRESSION = `(() => { - const buttons = ${JSON.stringify([ - ...SEND_BUTTON_SELECTORS - ])}; - for (const sel of buttons) { - const btn = document.querySelector(sel); - if (btn && !btn.disabled) { - btn.click(); - return { ok: true, sentVia: 'button', selector: sel }; - } - } - const composers = ${JSON.stringify([ - ...COMPOSER_SELECTORS - ])}; - let composer = null; - for (const sel of composers) { - composer = document.querySelector(sel); - if (composer) break; - } - if (!composer) return { ok: false, error: 'composer-not-found' }; - composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); - composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); - return { ok: true, sentVia: 'enter' }; + const TIMELINE_SCROLL_METRICS_EXPRESSION = `(() => { + const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + if (!scroll) return { ok: false }; + const rect = scroll.getBoundingClientRect(); + return { + ok: true, + x: Math.floor(rect.left + rect.width / 2), + y: Math.floor(rect.top + Math.min(rect.height / 2, 120)), + scrollTop: scroll.scrollTop, + scrollHeight: scroll.scrollHeight, + clientHeight: scroll.clientHeight, + }; })()`; - function sendMessageExpression(text) { - return fillComposerExpression(text); - } async function listThreadsFromDom(session, sessionId, { limit = 50 } = {}) { const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { sessionId }); if (!Array.isArray(rows)) return []; - return rows.slice(0, limit).map((row)=>({ + return dedupeThreadsById(rows).slice(0, limit).map((row)=>({ threadId: String(row.threadId), title: String(row.title ?? ''), pinned: Boolean(row.pinned), @@ -8645,60 +8701,213 @@ var __webpack_modules__ = { throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); } } - async function readTurnsFromDom(session, sessionId, { limit = 100 } = {}) { - const turns = await session.evaluate(READ_THREAD_EXPRESSION, { + async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS } = {}) { + const deadline = Date.now() + timeoutMs; + while(Date.now() < deadline){ + const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { + sessionId + }); + if (gone) return; + await delay(250); + } + throw new Error(`ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); + } + async function startNewChatInDom(session, sessionId, { project } = {}) { + const result = await session.evaluate(startNewChatExpression(project), { sessionId }); - if (!Array.isArray(turns)) return []; - return turns.slice(-limit).map((turn)=>({ - turnKey: String(turn.turnKey), - role: turn.role === 'user' || turn.role === 'status' ? turn.role : 'assistant', - text: String(turn.text ?? '') - })); + if (!result?.ok) { + throw new Error(project ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` : 'ChatGPT Desktop "New chat" button not found'); + } + return { + via: result.via ?? 'unknown' + }; } - async function sendMessageInDom(session, sessionId, text) { + async function focusComposer(session, sessionId) { const focused = await session.evaluate(FOCUS_COMPOSER_EXPRESSION, { sessionId }); if (!focused?.ok) { - throw new Error('ChatGPT Desktop composer not found (experimental send path)'); + throw new Error('ChatGPT Desktop composer not found ([data-codex-composer=true])'); } - let inserted = false; - try { - await session.send('Input.insertText', { - text - }, { - sessionId - }); - inserted = true; - } catch { - inserted = false; - } - if (!inserted) { - const filled = await session.evaluate(fillComposerExpression(text), { - sessionId - }); - if (!filled?.ok) { - throw new Error(filled?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${filled?.error ?? 'fill-failed'}`); - } + } + async function submitComposerWithEnter(session, sessionId) { + const base = { + windowsVirtualKeyCode: 13, + code: 'Enter', + key: 'Enter', + text: '\r', + unmodifiedText: '\r' + }; + await session.send('Input.dispatchKeyEvent', { + type: 'rawKeyDown', + ...base + }, { + sessionId + }); + await session.send('Input.dispatchKeyEvent', { + type: 'char', + ...base + }, { + sessionId + }); + await session.send('Input.dispatchKeyEvent', { + type: 'keyUp', + ...base + }, { + sessionId + }); + } + async function submitComposerWithButton(session, sessionId) { + const result = await session.evaluate(`(() => { + const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); + if (!btn || btn.disabled) return { ok: false }; + btn.click(); + return { ok: true }; + })()`, { + sessionId + }); + return Boolean(result?.ok); + } + async function sendMessageInDom(session, sessionId, text) { + await focusComposer(session, sessionId); + await session.send('Input.insertText', { + text + }, { + sessionId + }); + await submitComposerWithEnter(session, sessionId); + const sendStillVisible = await session.evaluate(`(() => { + const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); + return Boolean(btn && !btn.disabled); + })()`, { + sessionId + }); + if (sendStillVisible) { + const clicked = await submitComposerWithButton(session, sessionId); + if (clicked) return { + sentVia: 'button' + }; } - const submitted = await session.evaluate(SUBMIT_COMPOSER_EXPRESSION, { + return { + sentVia: 'enter' + }; + } + async function readReplyState(session, sessionId) { + const state = await session.evaluate(REPLY_STATE_EXPRESSION, { sessionId }); - if (!submitted?.ok) { - throw new Error(`ChatGPT Desktop send submit failed: ${submitted?.error ?? 'unknown'}`); + return { + stopVisible: Boolean(state?.stopVisible), + finalAssistantCount: Number(state?.finalAssistantCount ?? 0), + conversationId: String(state?.conversationId ?? ''), + reply: String(state?.reply ?? ''), + lastTurnKey: String(state?.lastTurnKey ?? '') + }; + } + async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0 } = {}) { + const deadline = Date.now() + timeoutMs; + let sawStop = false; + const started = Date.now(); + while(Date.now() < deadline){ + const state = await readReplyState(session, sessionId); + if (state.stopVisible) sawStop = true; + const hasNewFinal = state.finalAssistantCount > baselineFinalCount && Boolean(state.reply); + if (!state.stopVisible && hasNewFinal && (sawStop || Date.now() - started > 1500)) { + return { + reply: state.reply, + conversationId: state.conversationId + }; + } + await delay(200); + } + const last = await readReplyState(session, sessionId); + if (!last.stopVisible && last.finalAssistantCount > baselineFinalCount && last.reply) { + return { + reply: last.reply, + conversationId: last.conversationId + }; } + throw new Error(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); + } + function normalizeTurn(raw) { + const role = raw.role === 'user' || raw.role === 'status' || raw.role === 'assistant' ? raw.role : raw.assistantText ? 'assistant' : raw.userText ? 'user' : 'assistant'; return { - sentVia: submitted.sentVia ?? (inserted ? 'insertText' : 'dom') + turnKey: String(raw.turnKey ?? ''), + role, + text: String(raw.text ?? raw.assistantText ?? raw.userText ?? ''), + userText: raw.userText ? String(raw.userText) : undefined, + assistantText: raw.assistantText ? String(raw.assistantText) : undefined + }; + } + async function harvestVisibleTurns(session, sessionId) { + const rows = await session.evaluate(HARVEST_VISIBLE_TURNS_EXPRESSION, { + sessionId + }); + if (!Array.isArray(rows)) return []; + return rows.map(normalizeTurn).filter((t)=>t.turnKey && !t.turnKey.startsWith(HISTORY_GAP_PREFIX)); + } + async function readTurnsFromDom(session, sessionId, { limit = 100, full = false, threadId, idleWheels = DEFAULT_FULL_READ_IDLE_WHEELS, maxWheels = DEFAULT_FULL_READ_MAX_WHEELS } = {}) { + const collected = new Map(); + const ingest = async ()=>{ + for (const turn of (await harvestVisibleTurns(session, sessionId))){ + collected.set(turn.turnKey, turn); + } }; + await ingest(); + if (!full) { + const visible = [ + ...collected.values() + ]; + return limit > 0 ? visible.slice(-limit) : visible; + } + let idle = 0; + for(let step = 0; step < maxWheels; step++){ + const before = collected.size; + const metrics = await session.evaluate(TIMELINE_SCROLL_METRICS_EXPRESSION, { + sessionId + }); + if (!metrics?.ok || metrics.x == null || metrics.y == null) break; + await session.send('Input.dispatchMouseEvent', { + type: 'mouseWheel', + x: metrics.x, + y: metrics.y, + deltaX: 0, + deltaY: -800 + }, { + sessionId + }); + await delay(120); + await ingest(); + if (collected.size === before) { + idle += 1; + if (idle >= idleWheels) break; + } else { + idle = 0; + } + if (threadId && collected.has(threadId)) break; + } + const all = [ + ...collected.values() + ]; + return limit > 0 ? all.slice(0, limit) : all; + } + function delay(ms) { + return new Promise((resolve)=>setTimeout(resolve, ms)); } __webpack_require__.d(__webpack_exports__, { AY: ()=>listThreadsFromDom, C2: ()=>pickMainWindowTarget, + FG: ()=>waitForReplyDone, JU: ()=>readTurnsFromDom, Kl: ()=>openThreadInDom, Mr: ()=>summarizeTargetInfos, - lh: ()=>sendMessageInDom + YX: ()=>readReplyState, + Zx: ()=>waitForLoadingTaskGone, + lh: ()=>sendMessageInDom, + s0: ()=>startNewChatInDom + }, { + hA: TEMP_THREAD_ID_PREFIX }); }, "./src/core/chatgpt-desktop/cdp-session.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -8964,13 +9173,16 @@ var __webpack_modules__ = { return await this.#cdp.waitForReply(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return this.#fallbacks.waitForReply(options); + return this.#fallbacks.waitForReply({ + threadId: options.threadId ?? 'unknown', + timeoutMs: options.timeoutMs + }); } } - async openThread(threadId) { + async openThread(threadId, options) { try { await this.#ensureCdp(); - return await this.#cdp.openThread(threadId); + return await this.#cdp.openThread(threadId, options); } catch (error) { if (!isCdpFailure(error)) throw error; return this.#fallbacks.openThread(threadId); @@ -9107,17 +9319,21 @@ var __webpack_modules__ = { const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, - limit: zod__rspack_import_4.aig().int().min(1).max(500).default(100) + limit: zod__rspack_import_4.aig().int().min(1).max(2000).default(100), + full: zod__rspack_import_4.zMY().default(false), + openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); const sendSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), - text: zod__rspack_import_4.YjP().min(1).max(100000) + text: zod__rspack_import_4.YjP().min(1).max(100000), + project: zod__rspack_import_4.YjP().min(1).max(256).optional(), + openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); const waitReplySchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), - threadId, - timeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(60000) + threadId: threadId.optional(), + timeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(120000) }).strict(); const resultSchema = zod__rspack_import_4.Ikc({ exitCode: zod__rspack_import_4.KCZ([ @@ -9136,7 +9352,8 @@ var __webpack_modules__ = { return run(adapter); } function asResult(value) { - return resultSchema.parse(value); + const cleaned = Object.fromEntries(Object.entries(value).filter(([, entry])=>entry !== undefined)); + return resultSchema.parse(cleaned); } function mapError(error) { if (error instanceof _errors_js__rspack_import_1.EH) { @@ -9182,7 +9399,9 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ threadId: input.threadId, - limit: input.limit + limit: input.limit, + full: input.full, + openTimeoutMs: input.openTimeoutMs })); return asResult({ ...out, @@ -9196,7 +9415,9 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.sendMessage({ threadId: input.threadId, - text: input.text + text: input.text, + project: input.project, + openTimeoutMs: input.openTimeoutMs })); return asResult({ ...out, @@ -9231,13 +9452,15 @@ var __webpack_modules__ = { return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { - return `${result.turns.length} turns on ${result.threadId} via ${result.backend ?? 'unknown'}`; + const mode = result.full ? 'full' : 'visible'; + return `${result.turns.length} turns (${mode}) on ${result.threadId} via ${result.backend ?? 'unknown'}`; } if (result.delivery === 'accepted') { - return `Sent on ${result.threadId} via ${result.backend}${result.experimental ? ' (experimental)' : ''}`; + return `Sent on ${result.threadId} via ${result.backend}` + (result.conversationId ? ` (conversation ${result.conversationId})` : ''); } if (result.delivery === 'replied') { - return String(result.reply ?? 'replied'); + const id = result.conversationId ? ` [${result.conversationId}]` : ''; + return `${String(result.reply ?? 'replied')}${id}`; } if (result.delivery) return `delivery ${result.delivery}`; return JSON.stringify(result); @@ -9871,12 +10094,15 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.', + description: 'Open a ChatGPT Desktop sidebar thread (waits for Loading task… up to openTimeoutMs, default 90s) and harvest turns via local CDP. Default is visible turns only; full=true mouse-wheels the column-reverse timeline for history (skips history-gap placeholders). Falls back to Codex app-server when CDP is unreachable; result includes backend.', annotations: { readOnlyHint: true }, inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.so, resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + render: { + maxElapsedMs: 660000 + }, inputJsonSchema: { type: 'object', additionalProperties: false, @@ -9889,6 +10115,14 @@ var __webpack_modules__ = { }, limit: { type: 'number' + }, + full: { + type: 'boolean', + description: 'When true, wheel-crawl older history (slow). Default false = visible turns only.' + }, + openTimeoutMs: { + type: 'number', + description: 'Max wait for Loading task… to clear after opening (default 90000).' } }, required: [ @@ -9918,14 +10152,14 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop send', - description: 'EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.', + description: 'Send a message in ChatGPT Desktop via local CDP: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Falls back to app-server send when CDP is down and threadId is set.', annotations: { readOnlyHint: false }, inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.Wi, resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, render: { - maxElapsedMs: 120000 + maxElapsedMs: 180000 }, inputJsonSchema: { type: 'object', @@ -9936,10 +10170,17 @@ var __webpack_modules__ = { }, threadId: { type: 'string', - description: 'Sidebar thread id; omit to start/use a new chat.' + description: 'Sidebar thread id; omit to start a new chat.' }, text: { type: 'string' + }, + project: { + type: 'string', + description: 'Preferred project for new chats (Start new chat in ).' + }, + openTimeoutMs: { + type: 'number' } }, required: [ @@ -10009,7 +10250,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop wait for reply', - description: 'EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.', + description: 'Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). Falls back to app-server polling when CDP is unreachable.', annotations: { readOnlyHint: true }, @@ -10032,9 +10273,7 @@ var __webpack_modules__ = { type: 'number' } }, - required: [ - 'threadId' - ] + required: [] } }, async (input)=>{ const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.Zg)(input); @@ -25753,13 +25992,21 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.", + "description": "Open a ChatGPT Desktop sidebar thread (waits for Loading task… up to openTimeoutMs, default 90s) and harvest turns via local CDP. Default is visible turns only; full=true mouse-wheels the column-reverse timeline for history (skips history-gap placeholders). Falls back to Codex app-server when CDP is unreachable; result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "full": { + "description": "When true, wheel-crawl older history (slow). Default false = visible turns only.", + "type": "boolean" + }, "limit": { "type": "number" }, + "openTimeoutMs": { + "description": "Max wait for Loading task… to clear after opening (default 90000).", + "type": "number" + }, "port": { "type": "number" }, @@ -25772,6 +26019,9 @@ const routes = Object.freeze({ ], "type": "object" }, + "render": { + "maxElapsedMs": 660000 + }, "title": "ChatGPT Desktop read thread" }, id: "tool:grok-bot/chatgpt_desktop_read_thread", @@ -25785,18 +26035,25 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": false }, - "description": "EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.", + "description": "Send a message in ChatGPT Desktop via local CDP: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Falls back to app-server send when CDP is down and threadId is set.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "openTimeoutMs": { + "type": "number" + }, "port": { "type": "number" }, + "project": { + "description": "Preferred project for new chats (Start new chat in ).", + "type": "string" + }, "text": { "type": "string" }, "threadId": { - "description": "Sidebar thread id; omit to start/use a new chat.", + "description": "Sidebar thread id; omit to start a new chat.", "type": "string" } }, @@ -25806,7 +26063,7 @@ const routes = Object.freeze({ "type": "object" }, "render": { - "maxElapsedMs": 120000 + "maxElapsedMs": 180000 }, "title": "ChatGPT Desktop send" }, @@ -25846,7 +26103,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.", + "description": "Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). Falls back to app-server polling when CDP is unreachable.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -25860,9 +26117,7 @@ const routes = Object.freeze({ "type": "number" } }, - "required": [ - "threadId" - ], + "required": [], "type": "object" }, "render": { diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index d9f36bc..d676b00 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -6510,7 +6510,7 @@ var __webpack_modules__ = { })) }; } - async function appServerReadThread({ threadId, limit = 100 }) { + async function appServerReadThread({ threadId, limit = 100, full = false }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { let turns = []; @@ -6519,7 +6519,9 @@ var __webpack_modules__ = { threadId }); const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - turns = normalizeTurns(raw).slice(-limit); + turns = normalizeTurns(raw).slice(full ? 0 : -limit); + if (full && limit > 0) turns = turns.slice(0, limit); + else if (!full) turns = turns.slice(-limit); } catch { const items = await client.request('thread/items/list', { threadId, @@ -6531,7 +6533,8 @@ var __webpack_modules__ = { threadId, turns, backend: 'app-server', - limit + limit, + full }; } finally{ client.close(); @@ -6556,7 +6559,16 @@ var __webpack_modules__ = { message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined }; } - async function appServerWaitForReply({ threadId, timeoutMs = 60000 }) { + async function appServerWaitForReply({ threadId = 'unknown', timeoutMs = 60000 }) { + if (!threadId || threadId === 'unknown' || threadId === 'new') { + return { + threadId: threadId || 'unknown', + reply: '', + backend: 'app-server', + experimental: false, + delivery: 'rejected' + }; + } const baseline = await appServerReadThread({ threadId, limit: 200 @@ -6680,80 +6692,92 @@ var __webpack_modules__ = { limit }; } - async readThread({ threadId, limit = 100 }) { + async readThread({ threadId, limit = 100, full = false, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - await delay(150); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { - limit + limit, + full, + threadId }); return { threadId, turns, backend: 'cdp', - limit + limit, + full }; } - async sendMessage({ threadId, text }) { + async sendMessage({ threadId, text, project, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); + let temporaryThreadId; + let resolvedThreadId = threadId ?? 'new'; if (threadId) { - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - await delay(100); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); + } else { + await (0, _cdp_dom_js__rspack_import_2.s0)(this.#requireSession(), sessionId, { + project + }); + await delay(300); + const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + limit: 20 + }); + const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); + if (temp) { + temporaryThreadId = temp.threadId; + resolvedThreadId = temp.threadId; + } } - await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); return { - threadId: threadId ?? 'new', + threadId: resolvedThreadId, + temporaryThreadId, + project, backend: 'cdp', - experimental: true, + experimental: false, delivery: 'accepted', - message: 'Submitted via experimental CDP composer path' + sentVia, + message: 'Submitted via CDP composer (focus → insertText → Enter)' }; } - async waitForReply({ threadId, timeoutMs = 60000 }) { + async waitForReply({ threadId, timeoutMs = 120000 }) { const sessionId = await this.#ensurePageSession(); - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - const deadline = Date.now() + timeoutMs; - let previousKeys = new Set(); - let lastAssistant = ''; - let stable = 0; - const baseline = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { - limit: 500 - }); - previousKeys = new Set(baseline.map((t)=>t.turnKey)); - while(Date.now() < deadline){ - await delay(400); - const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { - limit: 500 + if (threadId && !threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && threadId !== 'new') { + try { + await this.#openAndWait(sessionId, threadId, 90000); + } catch {} + } + const baseline = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); + try { + const done = await (0, _cdp_dom_js__rspack_import_2.FG)(this.#requireSession(), sessionId, { + timeoutMs, + baselineFinalCount: baseline.finalAssistantCount }); - const fresh = turns.filter((t)=>!previousKeys.has(t.turnKey) && t.role === 'assistant'); - const candidate = fresh.at(-1)?.text ?? ''; - if (candidate && candidate === lastAssistant) { - stable += 1; - if (stable >= 3) { - return { - threadId, - reply: candidate, - backend: 'cdp', - experimental: true, - delivery: 'replied' - }; - } - } else if (candidate) { - lastAssistant = candidate; - stable = 0; - } + const resolvedId = done.conversationId || threadId || 'unknown'; + return { + threadId: resolvedId, + conversationId: done.conversationId || undefined, + reply: done.reply, + backend: 'cdp', + experimental: false, + delivery: 'replied' + }; + } catch (error) { + const last = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); + return { + threadId: last.conversationId || threadId || 'unknown', + conversationId: last.conversationId || undefined, + reply: last.reply, + backend: 'cdp', + experimental: false, + delivery: last.reply ? 'replied' : 'timeout', + ...error instanceof Error ? {} : {} + }; } - return { - threadId, - reply: lastAssistant, - backend: 'cdp', - experimental: true, - delivery: lastAssistant ? 'replied' : 'timeout' - }; } - async openThread(threadId) { + async openThread(threadId, { openTimeoutMs = 90000 } = {}) { const sessionId = await this.#ensurePageSession(); - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); return { threadId, backend: 'cdp' @@ -6801,6 +6825,12 @@ var __webpack_modules__ = { this.#session?.close(); this.#session = null; } + async #openAndWait(sessionId, threadId, openTimeoutMs) { + await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); + await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { + timeoutMs: openTimeoutMs + }); + } async #attachMainWindow() { const targets = await this.listTargets(); const main = (0, _cdp_dom_js__rspack_import_2.C2)(targets); @@ -6854,32 +6884,41 @@ var __webpack_modules__ = { turnKey: 'data-turn-key', userBubble: 'data-user-message-bubble', timelineScroll: 'data-app-action-timeline-scroll', - virtualizedTurn: 'data-virtualized-turn-content' + virtualizedTurn: 'data-virtualized-turn-content', + composer: 'data-codex-composer', + finalAssistant: 'data-local-conversation-final-assistant', + markdownTextStyle: 'data-markdown-text-style', + conversationAnnotation: 'data-response-annotation-conversation' }; const MAIN_CONTENT_SURFACE_CLASS_PREFIX = '_MainContentSurface'; - const COMPOSER_SELECTORS = [ - 'main [contenteditable="true"]', - 'main textarea', - '[data-app-action-composer] [contenteditable="true"]', - '[data-app-action-composer] textarea', - 'form [contenteditable="true"]', - 'form textarea' - ]; - const SEND_BUTTON_SELECTORS = [ - 'button[data-app-action-send]', - 'button[aria-label="Send"]', - 'button[aria-label="Send message"]', - 'main button[type="submit"]' - ]; + const HISTORY_GAP_PREFIX = 'history-gap:'; + const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; + const LOADING_TASK_TEXT = 'Loading task…'; + const DEFAULT_OPEN_TIMEOUT_MS = 90000; + const DEFAULT_FULL_READ_IDLE_WHEELS = 8; + const DEFAULT_FULL_READ_MAX_WHEELS = 400; + const COMPOSER_SELECTOR = `[${ATTR.composer}="true"][contenteditable="true"]`; + const SEND_BUTTON_SELECTOR = 'button[aria-label="Send"]'; + const STOP_BUTTON_SELECTOR = 'main button[aria-label="Stop"]'; + const FINAL_ASSISTANT_SELECTOR = `[${ATTR.finalAssistant}="true"]`; + const ASSISTANT_MESSAGE_SELECTOR = `[${ATTR.finalAssistant}="true"] [${ATTR.markdownTextStyle}="assistant-message"]`; + const CONVERSATION_ANNOTATION_SELECTOR = `[${ATTR.conversationAnnotation}]`; const SELECTORS = { threadRow: `[role="button"][${ATTR.threadRow}]`, turn: `[${ATTR.turnKey}]`, userBubble: `[${ATTR.userBubble}]`, timelineScroll: `[${ATTR.timelineScroll}]`, - mainSurface: 'main', - composerCandidates: COMPOSER_SELECTORS, - sendButtonCandidates: SEND_BUTTON_SELECTORS + composer: COMPOSER_SELECTOR, + sendButton: SEND_BUTTON_SELECTOR, + stopButton: STOP_BUTTON_SELECTOR, + finalAssistant: FINAL_ASSISTANT_SELECTOR, + assistantMessage: ASSISTANT_MESSAGE_SELECTOR, + conversationAnnotation: CONVERSATION_ANNOTATION_SELECTOR, + newChatFallback: 'button' }; + function newChatInProjectSelector(project) { + return `button[aria-label=${JSON.stringify(`Start new chat in ${project}`)}]`; + } function isMainWindowTarget(target) { if (target.type !== 'page') return false; const url = typeof target.url === 'string' ? target.url : ''; @@ -6898,15 +6937,33 @@ var __webpack_modules__ = { function pickMainWindowTarget(targets) { return targets.find((t)=>isMainWindowTarget(t)) ?? null; } + function dedupeThreadsById(threads) { + const seen = new Set(); + const out = []; + for (const thread of threads){ + if (!thread.threadId || seen.has(thread.threadId)) continue; + seen.add(thread.threadId); + out.push(thread); + } + return out; + } const LIST_THREADS_EXPRESSION = `(() => { const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); - return rows.map((row) => ({ - threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || '', - title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), - pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', - selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', - kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', - })).filter((t) => t.threadId); + const seen = new Set(); + const out = []; + for (const row of rows) { + const threadId = row.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''; + if (!threadId || seen.has(threadId)) continue; + seen.add(threadId); + out.push({ + threadId, + title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), + pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', + selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', + kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + }); + } + return out; })()`; function openThreadExpression(threadId) { return `(() => { @@ -6918,7 +6975,69 @@ var __webpack_modules__ = { return { ok: true, threadId: id }; })()`; } - const READ_THREAD_EXPRESSION = `(() => { + function startNewChatExpression(project) { + const projectSel = project ? newChatInProjectSelector(project) : null; + return `(() => { + const projectSel = ${JSON.stringify(projectSel)}; + if (projectSel) { + const preferred = document.querySelector(projectSel); + if (preferred) { + preferred.click(); + return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; + } + } + const buttons = Array.from(document.querySelectorAll('button')); + const fallback = buttons.find((btn) => (btn.textContent || '').trim() === 'New chat'); + if (!fallback) return { ok: false, error: 'new-chat-not-found' }; + fallback.click(); + return { ok: true, via: 'fallback' }; + })()`; + } + const LOADING_TASK_GONE_EXPRESSION = `(() => { + const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; + const mains = Array.from(document.querySelectorAll('main')); + const surface = + mains.find((el) => typeof el.className === 'string' && el.className.includes(surfacePrefix)) + || (mains.length >= 2 ? mains[1] : null) + || mains[0] + || document.body; + const text = (surface.innerText || '').replace(/\\u2026/g, '…'); + return !text.includes(${JSON.stringify(LOADING_TASK_TEXT)}); +})()`; + const FOCUS_COMPOSER_EXPRESSION = `(() => { + const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.focus(); + return { ok: true }; +})()`; + const REPLY_STATE_EXPRESSION = `(() => { + const stop = document.querySelector(${JSON.stringify(STOP_BUTTON_SELECTOR)}); + const finals = Array.from(document.querySelectorAll(${JSON.stringify(FINAL_ASSISTANT_SELECTOR)})); + const lastFinal = finals.at(-1) || null; + const annotation = lastFinal + ? lastFinal.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}) + || lastFinal.closest(${JSON.stringify(SELECTORS.turn)})?.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}) + : document.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}); + const conversationId = annotation + ? (annotation.getAttribute(${JSON.stringify(ATTR.conversationAnnotation)}) || '') + : ''; + const messageEl = lastFinal + ? lastFinal.querySelector(${JSON.stringify(`[${ATTR.markdownTextStyle}="assistant-message"]`)}) + : null; + const reply = messageEl ? (messageEl.innerText || '').trim() : ''; + const turns = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.turn)})); + const lastTurn = turns.at(-1); + const lastTurnKey = lastTurn ? (lastTurn.getAttribute(${JSON.stringify(ATTR.turnKey)}) || '') : ''; + return { + stopVisible: Boolean(stop), + finalAssistantCount: finals.length, + conversationId, + reply, + lastTurnKey, + }; +})()`; + const HARVEST_VISIBLE_TURNS_EXPRESSION = `(() => { + const gapPrefix = ${JSON.stringify(HISTORY_GAP_PREFIX)}; const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); const surface = @@ -6930,114 +7049,51 @@ var __webpack_modules__ = { surface.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}) || document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); const root = scroll || surface; - const collected = new Map(); - const statusRe = /^Worked for \\d+s$/i; - const harvest = () => { - for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { - const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; - if (!turnKey || collected.has(turnKey)) continue; - const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); - const text = (el.innerText || '').trim(); - let role = 'assistant'; - if (user) role = 'user'; - else if (!text || statusRe.test(text)) role = 'status'; - collected.set(turnKey, { turnKey, role, text }); - } - }; - const maxPasses = 80; - let stable = 0; - let lastSize = -1; - if (scroll) scroll.scrollTop = 0; - for (let i = 0; i < maxPasses; i++) { - harvest(); - if (collected.size === lastSize) { - stable += 1; - if (stable >= 3) break; - } else { - stable = 0; - lastSize = collected.size; - } - if (scroll) { - const next = Math.min(scroll.scrollHeight, scroll.scrollTop + Math.max(scroll.clientHeight, 200)); - if (next <= scroll.scrollTop && stable >= 1) break; - scroll.scrollTop = next; - } else { - break; + const out = []; + for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { + const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; + if (!turnKey || turnKey.startsWith(gapPrefix)) continue; + const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); + const assistant = el.querySelector(${JSON.stringify(ASSISTANT_MESSAGE_SELECTOR)}); + const userText = user ? (user.innerText || '').trim() : ''; + const assistantText = assistant ? (assistant.innerText || '').trim() : ''; + const raw = (el.innerText || '').trim(); + const statusRe = /^Worked for \\d+s$/i; + let role = 'assistant'; + let text = assistantText || userText || raw; + if (user && !assistantText) { + role = 'user'; + text = userText || raw; + } else if (assistantText) { + role = 'assistant'; + text = assistantText; + } else if (!raw || statusRe.test(raw)) { + role = 'status'; + text = raw; } + out.push({ turnKey, role, text, userText, assistantText }); } - harvest(); - return Array.from(collected.values()); + return out; })()`; - const FOCUS_COMPOSER_EXPRESSION = `(() => { - const composers = ${JSON.stringify([ - ...COMPOSER_SELECTORS - ])}; - for (const sel of composers) { - const composer = document.querySelector(sel); - if (!composer) continue; - composer.focus(); - return { ok: true, selector: sel, contentEditable: !!composer.isContentEditable }; - } - return { ok: false, error: 'composer-not-found' }; -})()`; - function fillComposerExpression(text) { - return `(() => { - const text = ${JSON.stringify(text)}; - const composers = ${JSON.stringify([ - ...COMPOSER_SELECTORS - ])}; - let composer = null; - for (const sel of composers) { - composer = document.querySelector(sel); - if (composer) break; - } - if (!composer) return { ok: false, error: 'composer-not-found' }; - composer.focus(); - if (composer.isContentEditable) { - composer.textContent = text; - composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: text, inputType: 'insertText' })); - } else if ('value' in composer) { - composer.value = text; - composer.dispatchEvent(new Event('input', { bubbles: true })); - } else { - return { ok: false, error: 'composer-unsupported' }; - } - return { ok: true }; - })()`; - } - const SUBMIT_COMPOSER_EXPRESSION = `(() => { - const buttons = ${JSON.stringify([ - ...SEND_BUTTON_SELECTORS - ])}; - for (const sel of buttons) { - const btn = document.querySelector(sel); - if (btn && !btn.disabled) { - btn.click(); - return { ok: true, sentVia: 'button', selector: sel }; - } - } - const composers = ${JSON.stringify([ - ...COMPOSER_SELECTORS - ])}; - let composer = null; - for (const sel of composers) { - composer = document.querySelector(sel); - if (composer) break; - } - if (!composer) return { ok: false, error: 'composer-not-found' }; - composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); - composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); - return { ok: true, sentVia: 'enter' }; + const TIMELINE_SCROLL_METRICS_EXPRESSION = `(() => { + const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + if (!scroll) return { ok: false }; + const rect = scroll.getBoundingClientRect(); + return { + ok: true, + x: Math.floor(rect.left + rect.width / 2), + y: Math.floor(rect.top + Math.min(rect.height / 2, 120)), + scrollTop: scroll.scrollTop, + scrollHeight: scroll.scrollHeight, + clientHeight: scroll.clientHeight, + }; })()`; - function sendMessageExpression(text) { - return fillComposerExpression(text); - } async function listThreadsFromDom(session, sessionId, { limit = 50 } = {}) { const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { sessionId }); if (!Array.isArray(rows)) return []; - return rows.slice(0, limit).map((row)=>({ + return dedupeThreadsById(rows).slice(0, limit).map((row)=>({ threadId: String(row.threadId), title: String(row.title ?? ''), pinned: Boolean(row.pinned), @@ -7053,60 +7109,213 @@ var __webpack_modules__ = { throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); } } - async function readTurnsFromDom(session, sessionId, { limit = 100 } = {}) { - const turns = await session.evaluate(READ_THREAD_EXPRESSION, { + async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS } = {}) { + const deadline = Date.now() + timeoutMs; + while(Date.now() < deadline){ + const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { + sessionId + }); + if (gone) return; + await delay(250); + } + throw new Error(`ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); + } + async function startNewChatInDom(session, sessionId, { project } = {}) { + const result = await session.evaluate(startNewChatExpression(project), { sessionId }); - if (!Array.isArray(turns)) return []; - return turns.slice(-limit).map((turn)=>({ - turnKey: String(turn.turnKey), - role: turn.role === 'user' || turn.role === 'status' ? turn.role : 'assistant', - text: String(turn.text ?? '') - })); + if (!result?.ok) { + throw new Error(project ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` : 'ChatGPT Desktop "New chat" button not found'); + } + return { + via: result.via ?? 'unknown' + }; } - async function sendMessageInDom(session, sessionId, text) { + async function focusComposer(session, sessionId) { const focused = await session.evaluate(FOCUS_COMPOSER_EXPRESSION, { sessionId }); if (!focused?.ok) { - throw new Error('ChatGPT Desktop composer not found (experimental send path)'); - } - let inserted = false; - try { - await session.send('Input.insertText', { - text - }, { - sessionId - }); - inserted = true; - } catch { - inserted = false; + throw new Error('ChatGPT Desktop composer not found ([data-codex-composer=true])'); } - if (!inserted) { - const filled = await session.evaluate(fillComposerExpression(text), { - sessionId - }); - if (!filled?.ok) { - throw new Error(filled?.error === 'composer-not-found' ? 'ChatGPT Desktop composer not found (experimental send path)' : `ChatGPT Desktop send failed: ${filled?.error ?? 'fill-failed'}`); - } + } + async function submitComposerWithEnter(session, sessionId) { + const base = { + windowsVirtualKeyCode: 13, + code: 'Enter', + key: 'Enter', + text: '\r', + unmodifiedText: '\r' + }; + await session.send('Input.dispatchKeyEvent', { + type: 'rawKeyDown', + ...base + }, { + sessionId + }); + await session.send('Input.dispatchKeyEvent', { + type: 'char', + ...base + }, { + sessionId + }); + await session.send('Input.dispatchKeyEvent', { + type: 'keyUp', + ...base + }, { + sessionId + }); + } + async function submitComposerWithButton(session, sessionId) { + const result = await session.evaluate(`(() => { + const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); + if (!btn || btn.disabled) return { ok: false }; + btn.click(); + return { ok: true }; + })()`, { + sessionId + }); + return Boolean(result?.ok); + } + async function sendMessageInDom(session, sessionId, text) { + await focusComposer(session, sessionId); + await session.send('Input.insertText', { + text + }, { + sessionId + }); + await submitComposerWithEnter(session, sessionId); + const sendStillVisible = await session.evaluate(`(() => { + const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); + return Boolean(btn && !btn.disabled); + })()`, { + sessionId + }); + if (sendStillVisible) { + const clicked = await submitComposerWithButton(session, sessionId); + if (clicked) return { + sentVia: 'button' + }; } - const submitted = await session.evaluate(SUBMIT_COMPOSER_EXPRESSION, { + return { + sentVia: 'enter' + }; + } + async function readReplyState(session, sessionId) { + const state = await session.evaluate(REPLY_STATE_EXPRESSION, { sessionId }); - if (!submitted?.ok) { - throw new Error(`ChatGPT Desktop send submit failed: ${submitted?.error ?? 'unknown'}`); + return { + stopVisible: Boolean(state?.stopVisible), + finalAssistantCount: Number(state?.finalAssistantCount ?? 0), + conversationId: String(state?.conversationId ?? ''), + reply: String(state?.reply ?? ''), + lastTurnKey: String(state?.lastTurnKey ?? '') + }; + } + async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0 } = {}) { + const deadline = Date.now() + timeoutMs; + let sawStop = false; + const started = Date.now(); + while(Date.now() < deadline){ + const state = await readReplyState(session, sessionId); + if (state.stopVisible) sawStop = true; + const hasNewFinal = state.finalAssistantCount > baselineFinalCount && Boolean(state.reply); + if (!state.stopVisible && hasNewFinal && (sawStop || Date.now() - started > 1500)) { + return { + reply: state.reply, + conversationId: state.conversationId + }; + } + await delay(200); } + const last = await readReplyState(session, sessionId); + if (!last.stopVisible && last.finalAssistantCount > baselineFinalCount && last.reply) { + return { + reply: last.reply, + conversationId: last.conversationId + }; + } + throw new Error(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); + } + function normalizeTurn(raw) { + const role = raw.role === 'user' || raw.role === 'status' || raw.role === 'assistant' ? raw.role : raw.assistantText ? 'assistant' : raw.userText ? 'user' : 'assistant'; return { - sentVia: submitted.sentVia ?? (inserted ? 'insertText' : 'dom') + turnKey: String(raw.turnKey ?? ''), + role, + text: String(raw.text ?? raw.assistantText ?? raw.userText ?? ''), + userText: raw.userText ? String(raw.userText) : undefined, + assistantText: raw.assistantText ? String(raw.assistantText) : undefined + }; + } + async function harvestVisibleTurns(session, sessionId) { + const rows = await session.evaluate(HARVEST_VISIBLE_TURNS_EXPRESSION, { + sessionId + }); + if (!Array.isArray(rows)) return []; + return rows.map(normalizeTurn).filter((t)=>t.turnKey && !t.turnKey.startsWith(HISTORY_GAP_PREFIX)); + } + async function readTurnsFromDom(session, sessionId, { limit = 100, full = false, threadId, idleWheels = DEFAULT_FULL_READ_IDLE_WHEELS, maxWheels = DEFAULT_FULL_READ_MAX_WHEELS } = {}) { + const collected = new Map(); + const ingest = async ()=>{ + for (const turn of (await harvestVisibleTurns(session, sessionId))){ + collected.set(turn.turnKey, turn); + } }; + await ingest(); + if (!full) { + const visible = [ + ...collected.values() + ]; + return limit > 0 ? visible.slice(-limit) : visible; + } + let idle = 0; + for(let step = 0; step < maxWheels; step++){ + const before = collected.size; + const metrics = await session.evaluate(TIMELINE_SCROLL_METRICS_EXPRESSION, { + sessionId + }); + if (!metrics?.ok || metrics.x == null || metrics.y == null) break; + await session.send('Input.dispatchMouseEvent', { + type: 'mouseWheel', + x: metrics.x, + y: metrics.y, + deltaX: 0, + deltaY: -800 + }, { + sessionId + }); + await delay(120); + await ingest(); + if (collected.size === before) { + idle += 1; + if (idle >= idleWheels) break; + } else { + idle = 0; + } + if (threadId && collected.has(threadId)) break; + } + const all = [ + ...collected.values() + ]; + return limit > 0 ? all.slice(0, limit) : all; + } + function delay(ms) { + return new Promise((resolve)=>setTimeout(resolve, ms)); } __webpack_require__.d(__webpack_exports__, { AY: ()=>listThreadsFromDom, C2: ()=>pickMainWindowTarget, + FG: ()=>waitForReplyDone, JU: ()=>readTurnsFromDom, Kl: ()=>openThreadInDom, Mr: ()=>summarizeTargetInfos, - lh: ()=>sendMessageInDom + YX: ()=>readReplyState, + Zx: ()=>waitForLoadingTaskGone, + lh: ()=>sendMessageInDom, + s0: ()=>startNewChatInDom + }, { + hA: TEMP_THREAD_ID_PREFIX }); }, "./src/core/chatgpt-desktop/cdp-session.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -7372,13 +7581,16 @@ var __webpack_modules__ = { return await this.#cdp.waitForReply(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return this.#fallbacks.waitForReply(options); + return this.#fallbacks.waitForReply({ + threadId: options.threadId ?? 'unknown', + timeoutMs: options.timeoutMs + }); } } - async openThread(threadId) { + async openThread(threadId, options) { try { await this.#ensureCdp(); - return await this.#cdp.openThread(threadId); + return await this.#cdp.openThread(threadId, options); } catch (error) { if (!isCdpFailure(error)) throw error; return this.#fallbacks.openThread(threadId); @@ -7515,17 +7727,21 @@ var __webpack_modules__ = { const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, - limit: zod__rspack_import_4.aig().int().min(1).max(500).default(100) + limit: zod__rspack_import_4.aig().int().min(1).max(2000).default(100), + full: zod__rspack_import_4.zMY().default(false), + openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); const sendSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), - text: zod__rspack_import_4.YjP().min(1).max(100000) + text: zod__rspack_import_4.YjP().min(1).max(100000), + project: zod__rspack_import_4.YjP().min(1).max(256).optional(), + openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); const waitReplySchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), - threadId, - timeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(60000) + threadId: threadId.optional(), + timeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(120000) }).strict(); const resultSchema = zod__rspack_import_4.Ikc({ exitCode: zod__rspack_import_4.KCZ([ @@ -7544,7 +7760,8 @@ var __webpack_modules__ = { return run(adapter); } function asResult(value) { - return resultSchema.parse(value); + const cleaned = Object.fromEntries(Object.entries(value).filter(([, entry])=>entry !== undefined)); + return resultSchema.parse(cleaned); } function mapError(error) { if (error instanceof _errors_js__rspack_import_1.EH) { @@ -7590,7 +7807,9 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ threadId: input.threadId, - limit: input.limit + limit: input.limit, + full: input.full, + openTimeoutMs: input.openTimeoutMs })); return asResult({ ...out, @@ -7604,7 +7823,9 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.sendMessage({ threadId: input.threadId, - text: input.text + text: input.text, + project: input.project, + openTimeoutMs: input.openTimeoutMs })); return asResult({ ...out, @@ -7639,13 +7860,15 @@ var __webpack_modules__ = { return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { - return `${result.turns.length} turns on ${result.threadId} via ${result.backend ?? 'unknown'}`; + const mode = result.full ? 'full' : 'visible'; + return `${result.turns.length} turns (${mode}) on ${result.threadId} via ${result.backend ?? 'unknown'}`; } if (result.delivery === 'accepted') { - return `Sent on ${result.threadId} via ${result.backend}${result.experimental ? ' (experimental)' : ''}`; + return `Sent on ${result.threadId} via ${result.backend}` + (result.conversationId ? ` (conversation ${result.conversationId})` : ''); } if (result.delivery === 'replied') { - return String(result.reply ?? 'replied'); + const id = result.conversationId ? ` [${result.conversationId}]` : ''; + return `${String(result.reply ?? 'replied')}${id}`; } if (result.delivery) return `delivery ${result.delivery}`; return JSON.stringify(result); @@ -8279,12 +8502,15 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.', + description: 'Open a ChatGPT Desktop sidebar thread (waits for Loading task… up to openTimeoutMs, default 90s) and harvest turns via local CDP. Default is visible turns only; full=true mouse-wheels the column-reverse timeline for history (skips history-gap placeholders). Falls back to Codex app-server when CDP is unreachable; result includes backend.', annotations: { readOnlyHint: true }, inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.so, resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + render: { + maxElapsedMs: 660000 + }, inputJsonSchema: { type: 'object', additionalProperties: false, @@ -8297,6 +8523,14 @@ var __webpack_modules__ = { }, limit: { type: 'number' + }, + full: { + type: 'boolean', + description: 'When true, wheel-crawl older history (slow). Default false = visible turns only.' + }, + openTimeoutMs: { + type: 'number', + description: 'Max wait for Loading task… to clear after opening (default 90000).' } }, required: [ @@ -8326,14 +8560,14 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop send', - description: 'EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.', + description: 'Send a message in ChatGPT Desktop via local CDP: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Falls back to app-server send when CDP is down and threadId is set.', annotations: { readOnlyHint: false }, inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.Wi, resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, render: { - maxElapsedMs: 120000 + maxElapsedMs: 180000 }, inputJsonSchema: { type: 'object', @@ -8344,10 +8578,17 @@ var __webpack_modules__ = { }, threadId: { type: 'string', - description: 'Sidebar thread id; omit to start/use a new chat.' + description: 'Sidebar thread id; omit to start a new chat.' }, text: { type: 'string' + }, + project: { + type: 'string', + description: 'Preferred project for new chats (Start new chat in ).' + }, + openTimeoutMs: { + type: 'number' } }, required: [ @@ -8417,7 +8658,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop wait for reply', - description: 'EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.', + description: 'Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). Falls back to app-server polling when CDP is unreachable.', annotations: { readOnlyHint: true }, @@ -8440,9 +8681,7 @@ var __webpack_modules__ = { type: 'number' } }, - required: [ - 'threadId' - ] + required: [] } }, async (input)=>{ const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.Zg)(input); @@ -57630,13 +57869,21 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.", + "description": "Open a ChatGPT Desktop sidebar thread (waits for Loading task… up to openTimeoutMs, default 90s) and harvest turns via local CDP. Default is visible turns only; full=true mouse-wheels the column-reverse timeline for history (skips history-gap placeholders). Falls back to Codex app-server when CDP is unreachable; result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "full": { + "description": "When true, wheel-crawl older history (slow). Default false = visible turns only.", + "type": "boolean" + }, "limit": { "type": "number" }, + "openTimeoutMs": { + "description": "Max wait for Loading task… to clear after opening (default 90000).", + "type": "number" + }, "port": { "type": "number" }, @@ -57649,6 +57896,9 @@ var __webpack_modules__ = { ], "type": "object" }, + "render": { + "maxElapsedMs": 660000 + }, "title": "ChatGPT Desktop read thread" }, id: "tool:grok-bot/chatgpt_desktop_read_thread", @@ -57661,18 +57911,25 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": false }, - "description": "EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.", + "description": "Send a message in ChatGPT Desktop via local CDP: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Falls back to app-server send when CDP is down and threadId is set.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "openTimeoutMs": { + "type": "number" + }, "port": { "type": "number" }, + "project": { + "description": "Preferred project for new chats (Start new chat in ).", + "type": "string" + }, "text": { "type": "string" }, "threadId": { - "description": "Sidebar thread id; omit to start/use a new chat.", + "description": "Sidebar thread id; omit to start a new chat.", "type": "string" } }, @@ -57682,7 +57939,7 @@ var __webpack_modules__ = { "type": "object" }, "render": { - "maxElapsedMs": 120000 + "maxElapsedMs": 180000 }, "title": "ChatGPT Desktop send" }, @@ -57720,7 +57977,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.", + "description": "Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). Falls back to app-server polling when CDP is unreachable.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -57734,9 +57991,7 @@ var __webpack_modules__ = { "type": "number" } }, - "required": [ - "threadId" - ], + "required": [], "type": "object" }, "render": { diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index 9dd224e..bb32711 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -54,9 +54,16 @@ use it only as a cheap status hint. ## DOM module -All selectors live in `src/core/chatgpt-desktop/cdp-dom.ts` (sidebar -`data-app-action-sidebar-thread-*`, timeline scroll, `data-turn-key`, user -bubbles, experimental composer candidates). Do not add selectors elsewhere. +All selectors live in `src/core/chatgpt-desktop/cdp-dom.ts`: + +- Composer: `[data-codex-composer=true][contenteditable=true]` — `focus()` then `Input.insertText` +- Submit: Enter via `Input.dispatchKeyEvent` (rawKeyDown/char/keyUp), Send button fallback +- Reply done: `main button[aria-label="Stop"]` gone + new `[data-local-conversation-final-assistant=true]` +- Reply text: last turn’s `[data-local-conversation-final-assistant=true] [data-markdown-text-style=assistant-message]` +- New chat: `button[aria-label="Start new chat in "]` (preferred) or sidebar “New chat” +- Conversation id: `[data-response-annotation-conversation]` (resolves `local:client-new-thread:…`) +- Open: click sidebar row, wait until “Loading task…” clears (default 90s) +- Full read: mouseWheel (negative deltaY) on `[data-app-action-timeline-scroll]` (column-reverse); skip `history-gap:` keys ## Fallback diff --git a/src/cli/chatgpt-desktop/read.tsx b/src/cli/chatgpt-desktop/read.tsx index 5a75a39..0d122cb 100644 --- a/src/cli/chatgpt-desktop/read.tsx +++ b/src/cli/chatgpt-desktop/read.tsx @@ -9,24 +9,30 @@ import { } from '../../core/chatgpt-desktop/routes.js'; export const config = { - description: 'Read a ChatGPT Desktop thread via CDP (app-server fallback when CDP is down).', + description: + 'Read a ChatGPT Desktop thread via CDP. Default: visible turns. --full wheel-crawls history.', exitCode: 'result', positionals: ['threadId'], inputJsonSchema: { additionalProperties: false, properties: { + full: { default: false, type: 'boolean' }, limit: { default: 100, type: 'number' }, + openTimeoutMs: { default: 90000, type: 'number' }, port: { type: 'number' }, threadId: { type: 'string' }, }, required: ['threadId'], type: 'object', }, + render: { maxElapsedMs: 660000 }, } satisfies CliRouteConfig; export const inputSchema = z .object({ - limit: z.number().int().min(1).max(500).default(100), + full: z.boolean().default(false), + limit: z.number().int().min(1).max(2000).default(100), + openTimeoutMs: z.number().int().min(1).max(600_000).default(90_000), port: z.number().int().min(1).max(65535).optional(), threadId: z.string().min(1).max(256), }) @@ -42,10 +48,25 @@ export default async function chatgptDesktopRead({ turns.length > 0 ? turns .map((turn) => { - const row = turn as { role?: string; text?: string; turnKey?: string }; - return `[${row.role ?? '?'} ${row.turnKey ?? ''}] ${row.text ?? ''}`; + const row = turn as { + role?: string; + text?: string; + turnKey?: string; + userText?: string; + assistantText?: string; + }; + const body = + row.userText || row.assistantText + ? [ + row.userText ? `user: ${row.userText}` : null, + row.assistantText ? `assistant: ${row.assistantText}` : null, + ] + .filter(Boolean) + .join('\n') + : row.text ?? ''; + return `[${row.role ?? '?'} ${row.turnKey ?? ''}]\n${body}`; }) - .join('\n\n') + `\n\nbackend: ${String(out.backend ?? '')}` + .join('\n\n') + `\n\nbackend: ${String(out.backend ?? '')} full: ${String(out.full ?? false)}` : resultText(out); return ( diff --git a/src/cli/chatgpt-desktop/send.tsx b/src/cli/chatgpt-desktop/send.tsx index cf32534..669f118 100644 --- a/src/cli/chatgpt-desktop/send.tsx +++ b/src/cli/chatgpt-desktop/send.tsx @@ -10,25 +10,29 @@ import { export const config = { description: - 'EXPERIMENTAL: send to ChatGPT Desktop via CDP composer; omit threadId for a new/current chat. App-server fallback needs threadId.', + 'Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .', exitCode: 'result', positionals: ['text'], inputJsonSchema: { additionalProperties: false, properties: { + openTimeoutMs: { type: 'number' }, port: { type: 'number' }, + project: { type: 'string' }, text: { type: 'array', items: { type: 'string' } }, threadId: { type: 'string' }, }, required: ['text'], type: 'object', }, - render: { maxElapsedMs: 120000 }, + render: { maxElapsedMs: 180000 }, } satisfies CliRouteConfig; export const inputSchema = z .object({ + openTimeoutMs: z.number().int().min(1).max(600_000).default(90_000), port: z.number().int().min(1).max(65535).optional(), + project: z.string().min(1).max(256).optional(), text: z.array(z.string()).min(1), threadId: z.string().min(1).max(256).optional(), }) @@ -42,6 +46,8 @@ export default async function chatgptDesktopSend({ port: input.port, threadId: input.threadId, text: input.text.join(' ').trim(), + project: input.project, + openTimeoutMs: input.openTimeoutMs, }); return ( diff --git a/src/core/chatgpt-desktop/adapter.ts b/src/core/chatgpt-desktop/adapter.ts index 285c8c6..a1b2d1a 100644 --- a/src/core/chatgpt-desktop/adapter.ts +++ b/src/core/chatgpt-desktop/adapter.ts @@ -16,11 +16,30 @@ export interface ChatGptDesktopAdapter { connect(options: { port: number }): Promise; listTargets(): Promise; listThreads(options?: { limit?: number }): Promise; - readThread(options: { threadId: string; limit?: number }): Promise; - /** Omitting `threadId` starts a new thread (composer in a new chat). */ - sendMessage(options: { threadId?: string; text: string }): Promise; - waitForReply(options: { threadId: string; timeoutMs?: number }): Promise; - openThread(threadId: string): Promise; + readThread(options: { + threadId: string; + limit?: number; + full?: boolean; + openTimeoutMs?: number; + }): Promise; + /** + * Send text. With `threadId`, opens that thread first. Without `threadId`, + * starts a new chat (`project` prefers "Start new chat in "). + */ + sendMessage(options: { + threadId?: string; + text: string; + project?: string; + openTimeoutMs?: number; + }): Promise; + waitForReply(options: { + threadId?: string; + timeoutMs?: number; + }): Promise; + openThread( + threadId: string, + options?: { openTimeoutMs?: number }, + ): Promise; status(): Promise; close(): Promise; } diff --git a/src/core/chatgpt-desktop/app-server-fallback.ts b/src/core/chatgpt-desktop/app-server-fallback.ts index e210087..2b4d153 100644 --- a/src/core/chatgpt-desktop/app-server-fallback.ts +++ b/src/core/chatgpt-desktop/app-server-fallback.ts @@ -45,13 +45,14 @@ export async function appServerListThreads({ export async function appServerReadThread({ threadId, limit = 100, + full = false, }: { threadId: string; limit?: number; + full?: boolean; }): Promise { const { client } = await openCodexSession(); try { - // Prefer thread/read when the daemon supports it; fall back to items list. let turns: ReadThreadResult['turns'] = []; try { const read = await client.request('thread/read', { threadId }) as { @@ -60,7 +61,9 @@ export async function appServerReadThread({ items?: unknown[]; }; const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - turns = normalizeTurns(raw).slice(-limit); + turns = normalizeTurns(raw).slice(full ? 0 : -limit); + if (full && limit > 0) turns = turns.slice(0, limit); + else if (!full) turns = turns.slice(-limit); } catch { const items = await client.request('thread/items/list', { threadId, @@ -68,7 +71,7 @@ export async function appServerReadThread({ }) as { data?: unknown[] }; turns = normalizeTurns(items.data ?? []).slice(-limit); } - return { threadId, turns, backend: 'app-server', limit }; + return { threadId, turns, backend: 'app-server', limit, full }; } finally { client.close(); } @@ -102,12 +105,21 @@ export async function appServerSendMessage({ } export async function appServerWaitForReply({ - threadId, + threadId = 'unknown', timeoutMs = 60000, }: { - threadId: string; + threadId?: string; timeoutMs?: number; }): Promise { + if (!threadId || threadId === 'unknown' || threadId === 'new') { + return { + threadId: threadId || 'unknown', + reply: '', + backend: 'app-server', + experimental: false, + delivery: 'rejected', + }; + } // Reuse the existing session client; poll thread/items/list for a fresh agent message. const baseline = await appServerReadThread({ threadId, limit: 200 }); const seen = new Set(baseline.turns.map((turn) => turn.turnKey)); diff --git a/src/core/chatgpt-desktop/cdp-adapter.ts b/src/core/chatgpt-desktop/cdp-adapter.ts index 3670a7b..8fe6488 100644 --- a/src/core/chatgpt-desktop/cdp-adapter.ts +++ b/src/core/chatgpt-desktop/cdp-adapter.ts @@ -2,12 +2,18 @@ import type { ChatGptDesktopAdapter } from './adapter.js'; import { CdpUnreachableError } from './errors.js'; import { CdpSession } from './cdp-session.js'; import { + DEFAULT_OPEN_TIMEOUT_MS, + TEMP_THREAD_ID_PREFIX, listThreadsFromDom, openThreadInDom, pickMainWindowTarget, + readReplyState, readTurnsFromDom, sendMessageInDom, + startNewChatInDom, summarizeTargetInfos, + waitForLoadingTaskGone, + waitForReplyDone, } from './cdp-dom.js'; import { resolveCdpPort } from './loopback.js'; import type { @@ -52,14 +58,12 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { } catch (error) { session.close(); this.#session = null; - // Keep #port so status() can still probe /json/version on the same port. throw error; } } async listTargets(): Promise { const session = this.#requireSession(); - // Target.getTargets is authoritative; /json/list is incomplete and order-unstable. const result = await session.send('Target.getTargets'); return summarizeTargetInfos(result.targetInfos ?? []); } @@ -73,91 +77,118 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { async readThread({ threadId, limit = 100, + full = false, + openTimeoutMs = DEFAULT_OPEN_TIMEOUT_MS, }: { threadId: string; limit?: number; + full?: boolean; + openTimeoutMs?: number; }): Promise { const sessionId = await this.#ensurePageSession(); - await openThreadInDom(this.#requireSession(), sessionId, threadId); - // Allow the virtualized timeline to settle after the click. - await delay(150); - const turns = await readTurnsFromDom(this.#requireSession(), sessionId, { limit }); - return { threadId, turns, backend: 'cdp', limit }; + await this.#openAndWait(sessionId, threadId, openTimeoutMs); + const turns = await readTurnsFromDom(this.#requireSession(), sessionId, { + limit, + full, + threadId, + }); + return { threadId, turns, backend: 'cdp', limit, full }; } async sendMessage({ threadId, text, + project, + openTimeoutMs = DEFAULT_OPEN_TIMEOUT_MS, }: { threadId?: string; text: string; + project?: string; + openTimeoutMs?: number; }): Promise { const sessionId = await this.#ensurePageSession(); + let temporaryThreadId: string | undefined; + let resolvedThreadId = threadId ?? 'new'; + if (threadId) { - await openThreadInDom(this.#requireSession(), sessionId, threadId); - await delay(100); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); + } else { + await startNewChatInDom(this.#requireSession(), sessionId, { project }); + await delay(300); + const threads = await listThreadsFromDom(this.#requireSession(), sessionId, { limit: 20 }); + const temp = threads.find((t) => t.threadId.startsWith(TEMP_THREAD_ID_PREFIX) && t.selected) + ?? threads.find((t) => t.threadId.startsWith(TEMP_THREAD_ID_PREFIX)); + if (temp) { + temporaryThreadId = temp.threadId; + resolvedThreadId = temp.threadId; + } } - await sendMessageInDom(this.#requireSession(), sessionId, text); + + const { sentVia } = await sendMessageInDom(this.#requireSession(), sessionId, text); return { - threadId: threadId ?? 'new', + threadId: resolvedThreadId, + temporaryThreadId, + project, backend: 'cdp', - experimental: true, + experimental: false, delivery: 'accepted', - message: 'Submitted via experimental CDP composer path', + sentVia, + message: 'Submitted via CDP composer (focus → insertText → Enter)', }; } async waitForReply({ threadId, - timeoutMs = 60000, + timeoutMs = 120_000, }: { - threadId: string; + threadId?: string; timeoutMs?: number; }): Promise { const sessionId = await this.#ensurePageSession(); - await openThreadInDom(this.#requireSession(), sessionId, threadId); - const deadline = Date.now() + timeoutMs; - let previousKeys = new Set(); - let lastAssistant = ''; - let stable = 0; - - // Baseline existing turns so we wait for a *new* assistant turn. - const baseline = await readTurnsFromDom(this.#requireSession(), sessionId, { limit: 500 }); - previousKeys = new Set(baseline.map((t) => t.turnKey)); - - while (Date.now() < deadline) { - await delay(400); - const turns = await readTurnsFromDom(this.#requireSession(), sessionId, { limit: 500 }); - const fresh = turns.filter((t) => !previousKeys.has(t.turnKey) && t.role === 'assistant'); - const candidate = fresh.at(-1)?.text ?? ''; - if (candidate && candidate === lastAssistant) { - stable += 1; - if (stable >= 3) { - return { - threadId, - reply: candidate, - backend: 'cdp', - experimental: true, - delivery: 'replied', - }; - } - } else if (candidate) { - lastAssistant = candidate; - stable = 0; + if (threadId && !threadId.startsWith(TEMP_THREAD_ID_PREFIX) && threadId !== 'new') { + // Stay on the current chat for temp/new; otherwise ensure the thread is open. + try { + await this.#openAndWait(sessionId, threadId, DEFAULT_OPEN_TIMEOUT_MS); + } catch { + // If already on the thread after send, continue waiting. } } - return { - threadId, - reply: lastAssistant, - backend: 'cdp', - experimental: true, - delivery: lastAssistant ? 'replied' : 'timeout', - }; + + const baseline = await readReplyState(this.#requireSession(), sessionId); + try { + const done = await waitForReplyDone(this.#requireSession(), sessionId, { + timeoutMs, + baselineFinalCount: baseline.finalAssistantCount, + }); + const resolvedId = done.conversationId || threadId || 'unknown'; + return { + threadId: resolvedId, + conversationId: done.conversationId || undefined, + reply: done.reply, + backend: 'cdp', + experimental: false, + delivery: 'replied', + }; + } catch (error) { + const last = await readReplyState(this.#requireSession(), sessionId); + return { + threadId: last.conversationId || threadId || 'unknown', + conversationId: last.conversationId || undefined, + reply: last.reply, + backend: 'cdp', + experimental: false, + delivery: last.reply ? 'replied' : 'timeout', + ...(error instanceof Error ? {} : {}), + }; + } } - async openThread(threadId: string): Promise { + async openThread( + threadId: string, + { openTimeoutMs = DEFAULT_OPEN_TIMEOUT_MS }: { openTimeoutMs?: number } = {}, + ): Promise { const sessionId = await this.#ensurePageSession(); - await openThreadInDom(this.#requireSession(), sessionId, threadId); + await this.#openAndWait(sessionId, threadId, openTimeoutMs); return { threadId, backend: 'cdp' }; } @@ -171,7 +202,6 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { targetCount = targets.length; mainWindowTargetId = pickMainWindowTarget(targets)?.targetId ?? null; } else { - // Cheap probe without attaching: /json/list is incomplete but fine for a count hint. const list = await CdpSession.fetchJsonList(this.#port); targetCount = list.length; } @@ -211,6 +241,13 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { this.#session = null; } + async #openAndWait(sessionId: string, threadId: string, openTimeoutMs: number): Promise { + await openThreadInDom(this.#requireSession(), sessionId, threadId); + await waitForLoadingTaskGone(this.#requireSession(), sessionId, { + timeoutMs: openTimeoutMs, + }); + } + async #attachMainWindow(): Promise { const targets = await this.listTargets(); const main = pickMainWindowTarget(targets); diff --git a/src/core/chatgpt-desktop/cdp-dom.ts b/src/core/chatgpt-desktop/cdp-dom.ts index f64f989..4735225 100644 --- a/src/core/chatgpt-desktop/cdp-dom.ts +++ b/src/core/chatgpt-desktop/cdp-dom.ts @@ -1,39 +1,16 @@ /** - * ChatGPT Desktop DOM / data-layer for CDP Runtime.evaluate. + * ChatGPT Desktop DOM / data-layer for CDP Runtime.evaluate + Input events. * - * ALL selector and in-page data extraction lives in this module. The adapter - * and tools must not invent additional DOM selectors. - * - * Evidence (macOS ChatGPT.app, bundle id com.openai.codex, v26.924.22138, - * Electron with renamed `Codex Framework.framework`, Chrome 154): - * - Launch with `--remote-debugging-port` (fuses block Node inspect / RunAsNode - * but not this Chromium flag). Port binds to 127.0.0.1. Do not use - * `@electron/fuses read` (fails on the renamed framework). - * - Prefer CDP `Target.getTargets` (`/json/list` is incomplete + order-unstable). - * - Main window: type `page`, url exactly `app://-/index.html` (no query). - * Ignore avatar-overlay, detached-window, and chatgpt.com / codex-sandbox webviews. - * - Sidebar rows: `[role=button][data-app-action-sidebar-thread-row]` with - * `data-app-action-sidebar-thread-{id,title,pinned,selected,kind}` (ids like - * `local:`; kind seen: local). Rows are not links — click to open; URL - * does not change. - * - Thread surface: second `
` whose class starts with `_MainContentSurface`. - * - Turns: `[data-turn-key]`; user bubbles: `[data-user-message-bubble]`; - * timeline scroll: `[data-app-action-timeline-scroll]` (virtualized via - * `data-virtualized-turn-content`). Scroll top→bottom until turn keys stabilize. - * Voice turns that only show "Worked for Xs" → role `status`. - * - send/waitForReply: not fully explored — experimental composer constants below. + * ALL selector and in-page data extraction lives in this module. Verified live + * on macOS ChatGPT.app (com.openai.codex, Chrome 154). */ import type { ChatGptDesktopTarget, ChatGptDesktopThread, ChatGptDesktopTurn } from './types.js'; import type { CdpSession } from './cdp-session.js'; -/** Exact main-window URL; ignore everything else. */ +/** Exact main-window URL; ignore overlays / detached / webviews. */ export const MAIN_WINDOW_URL = 'app://-/index.html'; -/** - * URL fragments that must never be treated as the main ChatGPT window. - * Selection still uses exact `MAIN_WINDOW_URL` equality; these document rejects. - */ export const IGNORED_TARGET_URL_MARKERS = [ 'initialRoute=%2Favatar-overlay', 'detached-window.html', @@ -52,42 +29,58 @@ export const ATTR = { userBubble: 'data-user-message-bubble', timelineScroll: 'data-app-action-timeline-scroll', virtualizedTurn: 'data-virtualized-turn-content', + composer: 'data-codex-composer', + finalAssistant: 'data-local-conversation-final-assistant', + markdownTextStyle: 'data-markdown-text-style', + conversationAnnotation: 'data-response-annotation-conversation', } as const; -/** Class-name prefix on the thread's `
` (second main in the document). */ export const MAIN_CONTENT_SURFACE_CLASS_PREFIX = '_MainContentSurface'; +export const HISTORY_GAP_PREFIX = 'history-gap:'; +export const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; +export const LOADING_TASK_TEXT = 'Loading task…'; +export const DEFAULT_OPEN_TIMEOUT_MS = 90_000; +export const DEFAULT_FULL_READ_IDLE_WHEELS = 8; +export const DEFAULT_FULL_READ_MAX_WHEELS = 400; -/** - * Experimental composer selectors (send/waitForReply not explored on-device yet). - * Prefer a contenteditable / textarea inside the main surface. - */ -export const COMPOSER_SELECTORS = [ - 'main [contenteditable="true"]', - 'main textarea', - '[data-app-action-composer] [contenteditable="true"]', - '[data-app-action-composer] textarea', - 'form [contenteditable="true"]', - 'form textarea', -] as const; +/** Verified composer: contenteditable textbox. */ +export const COMPOSER_SELECTOR = + `[${ATTR.composer}="true"][contenteditable="true"]` as const; -/** Experimental send-button selectors used after Input.insertText. */ -export const SEND_BUTTON_SELECTORS = [ - 'button[data-app-action-send]', - 'button[aria-label="Send"]', - 'button[aria-label="Send message"]', - 'main button[type="submit"]', -] as const; +/** Verified send button (only present while the composer has text). */ +export const SEND_BUTTON_SELECTOR = 'button[aria-label="Send"]' as const; + +/** Stop button in main — present while a reply is streaming. */ +export const STOP_BUTTON_SELECTOR = 'main button[aria-label="Stop"]' as const; + +/** Final assistant marker + markdown body inside a turn. */ +export const FINAL_ASSISTANT_SELECTOR = + `[${ATTR.finalAssistant}="true"]` as const; +export const ASSISTANT_MESSAGE_SELECTOR = + `[${ATTR.finalAssistant}="true"] [${ATTR.markdownTextStyle}="assistant-message"]` as const; + +/** Conversation id annotation inside a reply. */ +export const CONVERSATION_ANNOTATION_SELECTOR = + `[${ATTR.conversationAnnotation}]` as const; export const SELECTORS = { threadRow: `[role="button"][${ATTR.threadRow}]`, turn: `[${ATTR.turnKey}]`, userBubble: `[${ATTR.userBubble}]`, timelineScroll: `[${ATTR.timelineScroll}]`, - mainSurface: 'main', - composerCandidates: COMPOSER_SELECTORS, - sendButtonCandidates: SEND_BUTTON_SELECTORS, + composer: COMPOSER_SELECTOR, + sendButton: SEND_BUTTON_SELECTOR, + stopButton: STOP_BUTTON_SELECTOR, + finalAssistant: FINAL_ASSISTANT_SELECTOR, + assistantMessage: ASSISTANT_MESSAGE_SELECTOR, + conversationAnnotation: CONVERSATION_ANNOTATION_SELECTOR, + newChatFallback: 'button', } as const; +export function newChatInProjectSelector(project: string): string { + return `button[aria-label=${JSON.stringify(`Start new chat in ${project}`)}]`; +} + export function isMainWindowTarget(target: { type?: string; url?: string; @@ -95,8 +88,6 @@ export function isMainWindowTarget(target: { if (target.type !== 'page') return false; const url = typeof target.url === 'string' ? target.url : ''; if (url !== MAIN_WINDOW_URL) return false; - // Exact match already excludes query overlays / detached / webviews; markers - // are a belt-and-suspenders guard if a caller passes a looser URL later. return !IGNORED_TARGET_URL_MARKERS.some((marker) => url.includes(marker)); } @@ -126,19 +117,39 @@ export function pickMainWindowTarget( return targets.find((t) => isMainWindowTarget(t)) ?? null; } -/** In-page script: list sidebar threads from data attributes. */ +/** Dedupe sidebar rows (Recent + project can both list the same id). */ +export function dedupeThreadsById( + threads: readonly ChatGptDesktopThread[], +): ChatGptDesktopThread[] { + const seen = new Set(); + const out: ChatGptDesktopThread[] = []; + for (const thread of threads) { + if (!thread.threadId || seen.has(thread.threadId)) continue; + seen.add(thread.threadId); + out.push(thread); + } + return out; +} + export const LIST_THREADS_EXPRESSION = `(() => { const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); - return rows.map((row) => ({ - threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || '', - title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), - pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', - selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', - kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', - })).filter((t) => t.threadId); + const seen = new Set(); + const out = []; + for (const row of rows) { + const threadId = row.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''; + if (!threadId || seen.has(threadId)) continue; + seen.add(threadId); + out.push({ + threadId, + title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), + pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', + selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', + kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + }); + } + return out; })()`; -/** In-page script: click a sidebar row by thread id (URL does not change). */ export function openThreadExpression(threadId: string): string { return `(() => { const id = ${JSON.stringify(threadId)}; @@ -150,13 +161,77 @@ export function openThreadExpression(threadId: string): string { })()`; } +export function startNewChatExpression(project?: string): string { + const projectSel = project ? newChatInProjectSelector(project) : null; + return `(() => { + const projectSel = ${JSON.stringify(projectSel)}; + if (projectSel) { + const preferred = document.querySelector(projectSel); + if (preferred) { + preferred.click(); + return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; + } + } + const buttons = Array.from(document.querySelectorAll('button')); + const fallback = buttons.find((btn) => (btn.textContent || '').trim() === 'New chat'); + if (!fallback) return { ok: false, error: 'new-chat-not-found' }; + fallback.click(); + return { ok: true, via: 'fallback' }; + })()`; +} + +export const LOADING_TASK_GONE_EXPRESSION = `(() => { + const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; + const mains = Array.from(document.querySelectorAll('main')); + const surface = + mains.find((el) => typeof el.className === 'string' && el.className.includes(surfacePrefix)) + || (mains.length >= 2 ? mains[1] : null) + || mains[0] + || document.body; + const text = (surface.innerText || '').replace(/\\u2026/g, '…'); + return !text.includes(${JSON.stringify(LOADING_TASK_TEXT)}); +})()`; + +export const FOCUS_COMPOSER_EXPRESSION = `(() => { + const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + if (!composer) return { ok: false, error: 'composer-not-found' }; + composer.focus(); + return { ok: true }; +})()`; + +export const REPLY_STATE_EXPRESSION = `(() => { + const stop = document.querySelector(${JSON.stringify(STOP_BUTTON_SELECTOR)}); + const finals = Array.from(document.querySelectorAll(${JSON.stringify(FINAL_ASSISTANT_SELECTOR)})); + const lastFinal = finals.at(-1) || null; + const annotation = lastFinal + ? lastFinal.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}) + || lastFinal.closest(${JSON.stringify(SELECTORS.turn)})?.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}) + : document.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}); + const conversationId = annotation + ? (annotation.getAttribute(${JSON.stringify(ATTR.conversationAnnotation)}) || '') + : ''; + const messageEl = lastFinal + ? lastFinal.querySelector(${JSON.stringify(`[${ATTR.markdownTextStyle}="assistant-message"]`)}) + : null; + const reply = messageEl ? (messageEl.innerText || '').trim() : ''; + const turns = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.turn)})); + const lastTurn = turns.at(-1); + const lastTurnKey = lastTurn ? (lastTurn.getAttribute(${JSON.stringify(ATTR.turnKey)}) || '') : ''; + return { + stopVisible: Boolean(stop), + finalAssistantCount: finals.length, + conversationId, + reply, + lastTurnKey, + }; +})()`; + /** - * Scroll the virtualized timeline and collect turns keyed by data-turn-key. - * Prefer the second `
` whose class starts with `_MainContentSurface`. - * User turns contain [data-user-message-bubble]; other turns are assistant/status. - * Voice turns that only show "Worked for Xs" become status. + * Harvest currently rendered turns (no wheel). One turn may hold both the user + * bubble and the final assistant reply. Skip history-gap placeholders. */ -export const READ_THREAD_EXPRESSION = `(() => { +export const HARVEST_VISIBLE_TURNS_EXPRESSION = `(() => { + const gapPrefix = ${JSON.stringify(HISTORY_GAP_PREFIX)}; const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); const surface = @@ -168,109 +243,47 @@ export const READ_THREAD_EXPRESSION = `(() => { surface.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}) || document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); const root = scroll || surface; - const collected = new Map(); - const statusRe = /^Worked for \\d+s$/i; - const harvest = () => { - for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { - const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; - if (!turnKey || collected.has(turnKey)) continue; - const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); - const text = (el.innerText || '').trim(); - let role = 'assistant'; - if (user) role = 'user'; - else if (!text || statusRe.test(text)) role = 'status'; - collected.set(turnKey, { turnKey, role, text }); - } - }; - const maxPasses = 80; - let stable = 0; - let lastSize = -1; - if (scroll) scroll.scrollTop = 0; - for (let i = 0; i < maxPasses; i++) { - harvest(); - if (collected.size === lastSize) { - stable += 1; - if (stable >= 3) break; - } else { - stable = 0; - lastSize = collected.size; - } - if (scroll) { - const next = Math.min(scroll.scrollHeight, scroll.scrollTop + Math.max(scroll.clientHeight, 200)); - if (next <= scroll.scrollTop && stable >= 1) break; - scroll.scrollTop = next; - } else { - break; + const out = []; + for (const el of root.querySelectorAll(${JSON.stringify(SELECTORS.turn)})) { + const turnKey = el.getAttribute(${JSON.stringify(ATTR.turnKey)}) || ''; + if (!turnKey || turnKey.startsWith(gapPrefix)) continue; + const user = el.querySelector(${JSON.stringify(SELECTORS.userBubble)}); + const assistant = el.querySelector(${JSON.stringify(ASSISTANT_MESSAGE_SELECTOR)}); + const userText = user ? (user.innerText || '').trim() : ''; + const assistantText = assistant ? (assistant.innerText || '').trim() : ''; + const raw = (el.innerText || '').trim(); + const statusRe = /^Worked for \\d+s$/i; + let role = 'assistant'; + let text = assistantText || userText || raw; + if (user && !assistantText) { + role = 'user'; + text = userText || raw; + } else if (assistantText) { + role = 'assistant'; + text = assistantText; + } else if (!raw || statusRe.test(raw)) { + role = 'status'; + text = raw; } + out.push({ turnKey, role, text, userText, assistantText }); } - harvest(); - return Array.from(collected.values()); + return out; })()`; -/** Experimental: focus the first matching composer; returns whether it was found. */ -export const FOCUS_COMPOSER_EXPRESSION = `(() => { - const composers = ${JSON.stringify([...COMPOSER_SELECTORS])}; - for (const sel of composers) { - const composer = document.querySelector(sel); - if (!composer) continue; - composer.focus(); - return { ok: true, selector: sel, contentEditable: !!composer.isContentEditable }; - } - return { ok: false, error: 'composer-not-found' }; -})()`; - -/** Experimental: fill composer via DOM when Input.insertText is unavailable. */ -export function fillComposerExpression(text: string): string { - return `(() => { - const text = ${JSON.stringify(text)}; - const composers = ${JSON.stringify([...COMPOSER_SELECTORS])}; - let composer = null; - for (const sel of composers) { - composer = document.querySelector(sel); - if (composer) break; - } - if (!composer) return { ok: false, error: 'composer-not-found' }; - composer.focus(); - if (composer.isContentEditable) { - composer.textContent = text; - composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: text, inputType: 'insertText' })); - } else if ('value' in composer) { - composer.value = text; - composer.dispatchEvent(new Event('input', { bubbles: true })); - } else { - return { ok: false, error: 'composer-unsupported' }; - } - return { ok: true }; - })()`; -} - -/** Experimental: click send or press Enter on the focused composer. */ -export const SUBMIT_COMPOSER_EXPRESSION = `(() => { - const buttons = ${JSON.stringify([...SEND_BUTTON_SELECTORS])}; - for (const sel of buttons) { - const btn = document.querySelector(sel); - if (btn && !btn.disabled) { - btn.click(); - return { ok: true, sentVia: 'button', selector: sel }; - } - } - const composers = ${JSON.stringify([...COMPOSER_SELECTORS])}; - let composer = null; - for (const sel of composers) { - composer = document.querySelector(sel); - if (composer) break; - } - if (!composer) return { ok: false, error: 'composer-not-found' }; - composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); - composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); - return { ok: true, sentVia: 'enter' }; +export const TIMELINE_SCROLL_METRICS_EXPRESSION = `(() => { + const scroll = document.querySelector(${JSON.stringify(SELECTORS.timelineScroll)}); + if (!scroll) return { ok: false }; + const rect = scroll.getBoundingClientRect(); + return { + ok: true, + x: Math.floor(rect.left + rect.width / 2), + y: Math.floor(rect.top + Math.min(rect.height / 2, 120)), + scrollTop: scroll.scrollTop, + scrollHeight: scroll.scrollHeight, + clientHeight: scroll.clientHeight, + }; })()`; -/** @deprecated Prefer FOCUS + Input.insertText + SUBMIT; kept for tests/callers. */ -export function sendMessageExpression(text: string): string { - return fillComposerExpression(text); -} - export async function listThreadsFromDom( session: CdpSession, sessionId: string, @@ -278,7 +291,7 @@ export async function listThreadsFromDom( ): Promise { const rows = await session.evaluate(LIST_THREADS_EXPRESSION, { sessionId }); if (!Array.isArray(rows)) return []; - return rows.slice(0, limit).map((row) => ({ + return dedupeThreadsById(rows).slice(0, limit).map((row) => ({ threadId: String(row.threadId), title: String(row.title ?? ''), pinned: Boolean(row.pinned), @@ -297,70 +310,282 @@ export async function openThreadInDom( { sessionId }, ); if (!result?.ok) { - throw new Error(result?.error === 'thread-not-found' - ? `ChatGPT Desktop thread not found: ${threadId}` - : `Failed to open ChatGPT Desktop thread ${threadId}`); + throw new Error( + result?.error === 'thread-not-found' + ? `ChatGPT Desktop thread not found: ${threadId}` + : `Failed to open ChatGPT Desktop thread ${threadId}`, + ); } } -export async function readTurnsFromDom( +export async function waitForLoadingTaskGone( session: CdpSession, sessionId: string, - { limit = 100 }: { limit?: number } = {}, -): Promise { - const turns = await session.evaluate(READ_THREAD_EXPRESSION, { sessionId }); - if (!Array.isArray(turns)) return []; - return turns.slice(-limit).map((turn) => ({ - turnKey: String(turn.turnKey), - role: turn.role === 'user' || turn.role === 'status' ? turn.role : 'assistant', - text: String(turn.text ?? ''), - })); + { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS }: { timeoutMs?: number } = {}, +): Promise { + const deadline = Date.now() + timeoutMs; + while (Date.now() < deadline) { + const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { sessionId }); + if (gone) return; + await delay(250); + } + throw new Error( + `ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`, + ); } -/** - * Experimental send: focus composer → CDP Input.insertText → submit - * (send button or Enter). Falls back to DOM fill when insertText fails. - */ -export async function sendMessageInDom( +export async function startNewChatInDom( session: CdpSession, sessionId: string, - text: string, -): Promise<{ sentVia: string }> { + { project }: { project?: string } = {}, +): Promise<{ via: string }> { + const result = await session.evaluate<{ ok: boolean; via?: string; error?: string }>( + startNewChatExpression(project), + { sessionId }, + ); + if (!result?.ok) { + throw new Error( + project + ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` + : 'ChatGPT Desktop "New chat" button not found', + ); + } + return { via: result.via ?? 'unknown' }; +} + +export async function focusComposer( + session: CdpSession, + sessionId: string, +): Promise { const focused = await session.evaluate<{ ok: boolean; error?: string }>( FOCUS_COMPOSER_EXPRESSION, { sessionId }, ); if (!focused?.ok) { - throw new Error('ChatGPT Desktop composer not found (experimental send path)'); + throw new Error('ChatGPT Desktop composer not found ([data-codex-composer=true])'); } +} - let inserted = false; - try { - await session.send('Input.insertText', { text }, { sessionId }); - inserted = true; - } catch { - inserted = false; +/** Submit via Enter key events (preferred). */ +export async function submitComposerWithEnter( + session: CdpSession, + sessionId: string, +): Promise { + const base = { + windowsVirtualKeyCode: 13, + code: 'Enter', + key: 'Enter', + text: '\r', + unmodifiedText: '\r', + }; + await session.send('Input.dispatchKeyEvent', { type: 'rawKeyDown', ...base }, { sessionId }); + await session.send('Input.dispatchKeyEvent', { type: 'char', ...base }, { sessionId }); + await session.send('Input.dispatchKeyEvent', { type: 'keyUp', ...base }, { sessionId }); +} + +/** Fallback submit: click Send when the button exists (composer has text). */ +export async function submitComposerWithButton( + session: CdpSession, + sessionId: string, +): Promise { + const result = await session.evaluate<{ ok: boolean }>( + `(() => { + const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); + if (!btn || btn.disabled) return { ok: false }; + btn.click(); + return { ok: true }; + })()`, + { sessionId }, + ); + return Boolean(result?.ok); +} + +export async function sendMessageInDom( + session: CdpSession, + sessionId: string, + text: string, +): Promise<{ sentVia: 'enter' | 'button' }> { + await focusComposer(session, sessionId); + await session.send('Input.insertText', { text }, { sessionId }); + await submitComposerWithEnter(session, sessionId); + // Enter is the default; fall back to Send if the button is still present (composer still has text). + const sendStillVisible = await session.evaluate( + `(() => { + const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); + return Boolean(btn && !btn.disabled); + })()`, + { sessionId }, + ); + if (sendStillVisible) { + const clicked = await submitComposerWithButton(session, sessionId); + if (clicked) return { sentVia: 'button' }; } - if (!inserted) { - const filled = await session.evaluate<{ ok: boolean; error?: string }>( - fillComposerExpression(text), - { sessionId }, - ); - if (!filled?.ok) { - throw new Error( - filled?.error === 'composer-not-found' - ? 'ChatGPT Desktop composer not found (experimental send path)' - : `ChatGPT Desktop send failed: ${filled?.error ?? 'fill-failed'}`, - ); + return { sentVia: 'enter' }; +} + +export type ReplyState = { + stopVisible: boolean; + finalAssistantCount: number; + conversationId: string; + reply: string; + lastTurnKey: string; +}; + +export async function readReplyState( + session: CdpSession, + sessionId: string, +): Promise { + const state = await session.evaluate(REPLY_STATE_EXPRESSION, { sessionId }); + return { + stopVisible: Boolean(state?.stopVisible), + finalAssistantCount: Number(state?.finalAssistantCount ?? 0), + conversationId: String(state?.conversationId ?? ''), + reply: String(state?.reply ?? ''), + lastTurnKey: String(state?.lastTurnKey ?? ''), + }; +} + +/** + * Wait until Stop is gone and a new final-assistant marker exists. + * Returns reply text + conversation id from the annotation. + */ +export async function waitForReplyDone( + session: CdpSession, + sessionId: string, + { + timeoutMs = 120_000, + baselineFinalCount = 0, + }: { timeoutMs?: number; baselineFinalCount?: number } = {}, +): Promise<{ reply: string; conversationId: string }> { + const deadline = Date.now() + timeoutMs; + let sawStop = false; + const started = Date.now(); + while (Date.now() < deadline) { + const state = await readReplyState(session, sessionId); + if (state.stopVisible) sawStop = true; + const hasNewFinal = state.finalAssistantCount > baselineFinalCount && Boolean(state.reply); + // Stop appears within ~1s of submit; done when Stop is gone AND a new final exists. + if (!state.stopVisible && hasNewFinal && (sawStop || Date.now() - started > 1500)) { + return { reply: state.reply, conversationId: state.conversationId }; } + await delay(200); } + const last = await readReplyState(session, sessionId); + if (!last.stopVisible && last.finalAssistantCount > baselineFinalCount && last.reply) { + return { reply: last.reply, conversationId: last.conversationId }; + } + throw new Error(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); +} + +function normalizeTurn(raw: { + turnKey?: string; + role?: string; + text?: string; + userText?: string; + assistantText?: string; +}): ChatGptDesktopTurn { + const role = + raw.role === 'user' || raw.role === 'status' || raw.role === 'assistant' + ? raw.role + : raw.assistantText + ? 'assistant' + : raw.userText + ? 'user' + : 'assistant'; + return { + turnKey: String(raw.turnKey ?? ''), + role, + text: String(raw.text ?? raw.assistantText ?? raw.userText ?? ''), + userText: raw.userText ? String(raw.userText) : undefined, + assistantText: raw.assistantText ? String(raw.assistantText) : undefined, + }; +} - const submitted = await session.evaluate<{ ok: boolean; sentVia?: string; error?: string }>( - SUBMIT_COMPOSER_EXPRESSION, +export async function harvestVisibleTurns( + session: CdpSession, + sessionId: string, +): Promise { + const rows = await session.evaluate[0]>>( + HARVEST_VISIBLE_TURNS_EXPRESSION, { sessionId }, ); - if (!submitted?.ok) { - throw new Error(`ChatGPT Desktop send submit failed: ${submitted?.error ?? 'unknown'}`); + if (!Array.isArray(rows)) return []; + return rows.map(normalizeTurn).filter((t) => t.turnKey && !t.turnKey.startsWith(HISTORY_GAP_PREFIX)); +} + +/** + * Full history crawl: the timeline is column-reverse; scrollTop scripting does + * not load older turns (yields history-gap placeholders). Wheel with negative + * deltaY over the container, collect by data-turn-key, skip history-gap keys, + * stop after idle wheels or when a turn key equals the thread id. + */ +export async function readTurnsFromDom( + session: CdpSession, + sessionId: string, + { + limit = 100, + full = false, + threadId, + idleWheels = DEFAULT_FULL_READ_IDLE_WHEELS, + maxWheels = DEFAULT_FULL_READ_MAX_WHEELS, + }: { + limit?: number; + full?: boolean; + threadId?: string; + idleWheels?: number; + maxWheels?: number; + } = {}, +): Promise { + const collected = new Map(); + const ingest = async () => { + for (const turn of await harvestVisibleTurns(session, sessionId)) { + collected.set(turn.turnKey, turn); + } + }; + + await ingest(); + if (!full) { + const visible = [...collected.values()]; + return limit > 0 ? visible.slice(-limit) : visible; + } + + let idle = 0; + for (let step = 0; step < maxWheels; step++) { + const before = collected.size; + const metrics = await session.evaluate<{ + ok: boolean; + x?: number; + y?: number; + }>(TIMELINE_SCROLL_METRICS_EXPRESSION, { sessionId }); + if (!metrics?.ok || metrics.x == null || metrics.y == null) break; + + await session.send( + 'Input.dispatchMouseEvent', + { + type: 'mouseWheel', + x: metrics.x, + y: metrics.y, + deltaX: 0, + deltaY: -800, + }, + { sessionId }, + ); + await delay(120); + await ingest(); + + if (collected.size === before) { + idle += 1; + if (idle >= idleWheels) break; + } else { + idle = 0; + } + if (threadId && collected.has(threadId)) break; } - return { sentVia: submitted.sentVia ?? (inserted ? 'insertText' : 'dom') }; + + const all = [...collected.values()]; + return limit > 0 ? all.slice(0, limit) : all; +} + +function delay(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); } diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index b07296e..370ff53 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -87,7 +87,12 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { } } - async readThread(options: { threadId: string; limit?: number }): Promise { + async readThread(options: { + threadId: string; + limit?: number; + full?: boolean; + openTimeoutMs?: number; + }): Promise { try { await this.#ensureCdp(); return await this.#cdp.readThread(options); @@ -97,7 +102,12 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { } } - async sendMessage(options: { threadId?: string; text: string }): Promise { + async sendMessage(options: { + threadId?: string; + text: string; + project?: string; + openTimeoutMs?: number; + }): Promise { try { await this.#ensureCdp(); return await this.#cdp.sendMessage(options); @@ -108,7 +118,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { } async waitForReply(options: { - threadId: string; + threadId?: string; timeoutMs?: number; }): Promise { try { @@ -116,14 +126,20 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { return await this.#cdp.waitForReply(options); } catch (error) { if (!isCdpFailure(error)) throw error; - return this.#fallbacks.waitForReply(options); + return this.#fallbacks.waitForReply({ + threadId: options.threadId ?? 'unknown', + timeoutMs: options.timeoutMs, + }); } } - async openThread(threadId: string): Promise { + async openThread( + threadId: string, + options?: { openTimeoutMs?: number }, + ): Promise { try { await this.#ensureCdp(); - return await this.#cdp.openThread(threadId); + return await this.#cdp.openThread(threadId, options); } catch (error) { if (!isCdpFailure(error)) throw error; return this.#fallbacks.openThread(threadId); diff --git a/src/core/chatgpt-desktop/index.ts b/src/core/chatgpt-desktop/index.ts index 58368b3..7426fae 100644 --- a/src/core/chatgpt-desktop/index.ts +++ b/src/core/chatgpt-desktop/index.ts @@ -1,14 +1,20 @@ export type { ChatGptDesktopAdapter } from './adapter.js'; export { CdpChatGptDesktopAdapter } from './cdp-adapter.js'; export { + ASSISTANT_MESSAGE_SELECTOR, ATTR, - COMPOSER_SELECTORS, + COMPOSER_SELECTOR, + FINAL_ASSISTANT_SELECTOR, IGNORED_TARGET_URL_MARKERS, MAIN_CONTENT_SURFACE_CLASS_PREFIX, MAIN_WINDOW_URL, SELECTORS, - SEND_BUTTON_SELECTORS, + SEND_BUTTON_SELECTOR, + STOP_BUTTON_SELECTOR, + TEMP_THREAD_ID_PREFIX, + dedupeThreadsById, isMainWindowTarget, + newChatInProjectSelector, pickMainWindowTarget, summarizeTargetInfos, } from './cdp-dom.js'; diff --git a/src/core/chatgpt-desktop/routes.ts b/src/core/chatgpt-desktop/routes.ts index 3628b84..86462cf 100644 --- a/src/core/chatgpt-desktop/routes.ts +++ b/src/core/chatgpt-desktop/routes.ts @@ -24,7 +24,9 @@ export const readThreadSchema = z .object({ port: z.number().int().min(1).max(65535).optional(), threadId, - limit: z.number().int().min(1).max(500).default(100), + limit: z.number().int().min(1).max(2000).default(100), + full: z.boolean().default(false), + openTimeoutMs: z.number().int().min(1).max(600_000).default(90_000), }) .strict(); @@ -33,14 +35,16 @@ export const sendSchema = z port: z.number().int().min(1).max(65535).optional(), threadId: threadId.optional(), text: z.string().min(1).max(100_000), + project: z.string().min(1).max(256).optional(), + openTimeoutMs: z.number().int().min(1).max(600_000).default(90_000), }) .strict(); export const waitReplySchema = z .object({ port: z.number().int().min(1).max(65535).optional(), - threadId, - timeoutMs: z.number().int().min(1).max(600_000).default(60_000), + threadId: threadId.optional(), + timeoutMs: z.number().int().min(1).max(600_000).default(120_000), }) .strict(); @@ -67,7 +71,10 @@ async function withAdapter( } function asResult(value: object): OperationResult { - return resultSchema.parse(value); + const cleaned = Object.fromEntries( + Object.entries(value).filter(([, entry]) => entry !== undefined), + ); + return resultSchema.parse(cleaned); } function mapError(error: unknown): OperationResult { @@ -114,7 +121,12 @@ export async function readThreadOperation( ): Promise { try { const out = await withAdapter(input.port, (adapter) => - adapter.readThread({ threadId: input.threadId, limit: input.limit }), + adapter.readThread({ + threadId: input.threadId, + limit: input.limit, + full: input.full, + openTimeoutMs: input.openTimeoutMs, + }), ); return asResult({ ...out, exitCode: 0 as const }); } catch (error) { @@ -125,7 +137,12 @@ export async function readThreadOperation( export async function sendOperation(input: z.infer): Promise { try { const out = await withAdapter(input.port, (adapter) => - adapter.sendMessage({ threadId: input.threadId, text: input.text }), + adapter.sendMessage({ + threadId: input.threadId, + text: input.text, + project: input.project, + openTimeoutMs: input.openTimeoutMs, + }), ); return asResult({ ...out, @@ -165,13 +182,16 @@ export function resultText(result: OperationResult): string { return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { - return `${result.turns.length} turns on ${result.threadId} via ${result.backend ?? 'unknown'}`; + const mode = result.full ? 'full' : 'visible'; + return `${result.turns.length} turns (${mode}) on ${result.threadId} via ${result.backend ?? 'unknown'}`; } if (result.delivery === 'accepted') { - return `Sent on ${result.threadId} via ${result.backend}${result.experimental ? ' (experimental)' : ''}`; + return `Sent on ${result.threadId} via ${result.backend}` + + (result.conversationId ? ` (conversation ${result.conversationId})` : ''); } if (result.delivery === 'replied') { - return String(result.reply ?? 'replied'); + const id = result.conversationId ? ` [${result.conversationId}]` : ''; + return `${String(result.reply ?? 'replied')}${id}`; } if (result.delivery) return `delivery ${result.delivery}`; return JSON.stringify(result); diff --git a/src/core/chatgpt-desktop/types.ts b/src/core/chatgpt-desktop/types.ts index a6f7a43..ab09e1a 100644 --- a/src/core/chatgpt-desktop/types.ts +++ b/src/core/chatgpt-desktop/types.ts @@ -20,6 +20,10 @@ export type ChatGptDesktopTurn = { readonly turnKey: string; readonly role: 'user' | 'assistant' | 'status'; readonly text: string; + /** User bubble text when the turn holds both sides. */ + readonly userText?: string; + /** Final assistant markdown when present on the same turn. */ + readonly assistantText?: string; }; export type ChatGptDesktopStatus = { @@ -51,6 +55,7 @@ export type ReadThreadResult = { readonly turns: readonly ChatGptDesktopTurn[]; readonly backend: ChatGptDesktopBackend; readonly limit: number; + readonly full: boolean; }; export type SendMessageResult = { @@ -59,6 +64,10 @@ export type SendMessageResult = { readonly experimental: boolean; readonly delivery: 'accepted' | 'rejected' | 'unknown'; readonly message?: string; + /** Temporary sidebar id before reload (`local:client-new-thread:…`). */ + readonly temporaryThreadId?: string; + readonly project?: string; + readonly sentVia?: 'enter' | 'button'; }; export type WaitForReplyResult = { @@ -67,6 +76,8 @@ export type WaitForReplyResult = { readonly backend: ChatGptDesktopBackend; readonly experimental: boolean; readonly delivery: 'replied' | 'timeout' | 'rejected' | 'unknown'; + /** Real conversation id from `data-response-annotation-conversation`. */ + readonly conversationId?: string; }; export type OpenThreadResult = { diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx index 0a6b8b2..81471ea 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx @@ -13,10 +13,11 @@ export default defineTool( { title: 'ChatGPT Desktop read thread', description: - 'Open a ChatGPT Desktop sidebar thread and collect turns via local CDP (scrolls the virtualized timeline). Falls back to Codex app-server thread/read or items when CDP is unreachable; result includes backend.', + 'Open a ChatGPT Desktop sidebar thread (waits for Loading task… up to openTimeoutMs, default 90s) and harvest turns via local CDP. Default is visible turns only; full=true mouse-wheels the column-reverse timeline for history (skips history-gap placeholders). Falls back to Codex app-server when CDP is unreachable; result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, + render: { maxElapsedMs: 660000 }, inputJsonSchema: { type: 'object', additionalProperties: false, @@ -24,6 +25,14 @@ export default defineTool( port: { type: 'number' }, threadId: { type: 'string' }, limit: { type: 'number' }, + full: { + type: 'boolean', + description: 'When true, wheel-crawl older history (slow). Default false = visible turns only.', + }, + openTimeoutMs: { + type: 'number', + description: 'Max wait for Loading task… to clear after opening (default 90000).', + }, }, required: ['threadId'], }, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx index fb788e6..c03c81e 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx @@ -13,18 +13,23 @@ export default defineTool( { title: 'ChatGPT Desktop send', description: - 'EXPERIMENTAL: send a message in ChatGPT Desktop via local CDP composer (Input.insertText / contenteditable). Omit threadId to use the current/new chat. Falls back to Codex app-server send when CDP is unreachable and threadId is set; result includes backend.', + 'Send a message in ChatGPT Desktop via local CDP: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Falls back to app-server send when CDP is down and threadId is set.', annotations: { readOnlyHint: false }, inputSchema, resultSchema, - render: { maxElapsedMs: 120000 }, + render: { maxElapsedMs: 180000 }, inputJsonSchema: { type: 'object', additionalProperties: false, properties: { port: { type: 'number' }, - threadId: { type: 'string', description: 'Sidebar thread id; omit to start/use a new chat.' }, + threadId: { type: 'string', description: 'Sidebar thread id; omit to start a new chat.' }, text: { type: 'string' }, + project: { + type: 'string', + description: 'Preferred project for new chats (Start new chat in ).', + }, + openTimeoutMs: { type: 'number' }, }, required: ['text'], }, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx index 8ee0146..b865b11 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop wait for reply', description: - 'EXPERIMENTAL: poll ChatGPT Desktop turns via local CDP until a new assistant turn stabilizes, or time out. Falls back to Codex app-server item polling when CDP is unreachable; result includes backend.', + 'Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). Falls back to app-server polling when CDP is unreachable.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -26,7 +26,7 @@ export default defineTool( threadId: { type: 'string' }, timeoutMs: { type: 'number' }, }, - required: ['threadId'], + required: [], }, }, async (input) => { diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index b074d9e..60b9aa7 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -53,32 +53,42 @@ function fakeAdapter(overrides: Partial = {}): ChatGptDes ].slice(0, limit), }; }, - async readThread({ threadId, limit = 100 }) { + async readThread({ threadId, limit = 100, full = false }) { return { threadId, backend: 'cdp', limit, + full, turns: [ - { turnKey: 'u1', role: 'user', text: 'hello' }, - { turnKey: 'a1', role: 'assistant', text: 'hi there' }, + { + turnKey: 't1', + role: 'assistant', + text: 'hi there', + userText: 'hello', + assistantText: 'hi there', + }, ], }; }, - async sendMessage({ threadId, text }) { + async sendMessage({ threadId, text, project }) { return { - threadId: threadId ?? 'new', + threadId: threadId ?? 'local:client-new-thread:deadbeef', + temporaryThreadId: threadId ? undefined : 'local:client-new-thread:deadbeef', + project, backend: 'cdp', - experimental: true, + experimental: false, delivery: 'accepted', + sentVia: 'enter', message: text, }; }, async waitForReply({ threadId }) { return { - threadId, + threadId: threadId ?? 'conv-real-id', + conversationId: 'conv-real-id', reply: 'hi there', backend: 'cdp', - experimental: true, + experimental: false, delivery: 'replied', }; }, @@ -125,9 +135,13 @@ describe('chatgpt-desktop loopback + relaunch helpers', () => { const { IGNORED_TARGET_URL_MARKERS, MAIN_WINDOW_URL, - COMPOSER_SELECTORS, - SEND_BUTTON_SELECTORS, + COMPOSER_SELECTOR, + SEND_BUTTON_SELECTOR, + STOP_BUTTON_SELECTOR, + ASSISTANT_MESSAGE_SELECTOR, + dedupeThreadsById, isMainWindowTarget, + newChatInProjectSelector, pickMainWindowTarget, summarizeTargetInfos, } = await import('../../src/core/chatgpt-desktop/cdp-dom.js'); @@ -142,8 +156,18 @@ describe('chatgpt-desktop loopback + relaunch helpers', () => { expect(isMainWindowTarget({ type: 'page', url: 'app://-/detached-window.html' })).toBe(false); expect(isMainWindowTarget({ type: 'page', url: 'https://chatgpt.com/pricing' })).toBe(false); expect(IGNORED_TARGET_URL_MARKERS.length).toBeGreaterThan(0); - expect(COMPOSER_SELECTORS[0]).toContain('contenteditable'); - expect(SEND_BUTTON_SELECTORS.length).toBeGreaterThan(0); + expect(COMPOSER_SELECTOR).toContain('data-codex-composer'); + expect(SEND_BUTTON_SELECTOR).toBe('button[aria-label="Send"]'); + expect(STOP_BUTTON_SELECTOR).toContain('Stop'); + expect(ASSISTANT_MESSAGE_SELECTOR).toContain('assistant-message'); + expect(newChatInProjectSelector('Launch')).toContain('Start new chat in Launch'); + expect( + dedupeThreadsById([ + { threadId: 'a', title: '1', pinned: false, selected: false, kind: 'local' }, + { threadId: 'a', title: '1b', pinned: false, selected: true, kind: 'local' }, + { threadId: 'b', title: '2', pinned: false, selected: false, kind: 'local' }, + ]).map((t) => t.threadId), + ).toEqual(['a', 'b']); const targets = summarizeTargetInfos([ { targetId: 'overlay', type: 'page', url: 'app://-/index.html?initialRoute=%2Favatar-overlay' }, @@ -194,29 +218,33 @@ describe('chatgpt-desktop MCP tools', () => { expect(read.isError).toBe(false); expect(read.structuredContent).toMatchObject({ backend: 'cdp', - turns: [{ role: 'user' }, { role: 'assistant' }], + full: false, + turns: [{ role: 'assistant', userText: 'hello', assistantText: 'hi there' }], }); const sent = await invokeMcpTool('chatgpt_desktop_send', { server: 'grok-bot', - input: { text: 'ping' }, + input: { text: 'ping', project: 'Launch' }, }); expect(sent.isError).toBe(false); expect(sent.structuredContent).toMatchObject({ delivery: 'accepted', backend: 'cdp', - experimental: true, + experimental: false, + temporaryThreadId: 'local:client-new-thread:deadbeef', + project: 'Launch', exitCode: 0, }); const waited = await invokeMcpTool('chatgpt_desktop_wait_reply', { server: 'grok-bot', - input: { threadId: 'local:11111111-1111-1111-1111-111111111111', timeoutMs: 1000 }, + input: { threadId: 'local:client-new-thread:deadbeef', timeoutMs: 1000 }, }); expect(waited.isError).toBe(false); expect(waited.structuredContent).toMatchObject({ delivery: 'replied', reply: 'hi there', + conversationId: 'conv-real-id', exitCode: 0, }); }); @@ -353,12 +381,13 @@ describe('chatgpt-desktop CDP→app-server fallback', () => { ], }; }, - readThread: async ({ threadId, limit = 100 }) => { + readThread: async ({ threadId, limit = 100, full = false }) => { calls.push('app-server.readThread'); return { threadId, backend: 'app-server', limit, + full, turns: [{ turnKey: 't1', role: 'assistant', text: 'fallback reply' }], }; }, @@ -373,7 +402,7 @@ describe('chatgpt-desktop CDP→app-server fallback', () => { }; }, waitForReply: async ({ threadId }) => ({ - threadId, + threadId: threadId ?? 'codex-1', reply: 'fallback reply', backend: 'app-server', experimental: false, From 5617e076bb784c4a14d2e552be4668d7cc92a369 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 00:57:15 +0000 Subject: [PATCH 06/26] docs: document chatgpt-desktop project send and full read Co-authored-by: Zack Jackson --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d67d158..f9c5e60 100644 --- a/README.md +++ b/README.md @@ -231,10 +231,12 @@ osascript -e 'tell application "ChatGPT" to quit' \ gbot chatgpt-desktop status gbot chatgpt-desktop threads --limit 20 gbot chatgpt-desktop read +gbot chatgpt-desktop read --full --limit 200 +gbot chatgpt-desktop send --project Launch "hello" gbot chatgpt-desktop send --thread-id "hello" ``` -MCP tools: `chatgpt_desktop_status`, `chatgpt_desktop_list_threads`, `chatgpt_desktop_read_thread`, `chatgpt_desktop_send`, `chatgpt_desktop_wait_reply`. List/read/send/wait fall back to the existing Codex app-server client when CDP is down and report `backend: "cdp" | "app-server"`. DOM selectors live in one module (`src/core/chatgpt-desktop/cdp-dom.ts`). Details: [docs/chatgpt-desktop-cdp.md](docs/chatgpt-desktop-cdp.md). +MCP tools: `chatgpt_desktop_status`, `chatgpt_desktop_list_threads`, `chatgpt_desktop_read_thread`, `chatgpt_desktop_send`, `chatgpt_desktop_wait_reply`. New chats prefer `project` (“Start new chat in …”); `wait_reply` resolves the real conversation id. Default read is visible turns; `--full` wheel-crawls history. List/read/send/wait fall back to the existing Codex app-server client when CDP is down and report `backend: "cdp" | "app-server"`. Details: [docs/chatgpt-desktop-cdp.md](docs/chatgpt-desktop-cdp.md). **Status contract (`gbot codex status --json`).** `reachable` is endpoint reachability only. `socketState` is `socket`, `absent`, `permission-denied`, or `not-a-socket`; `mode` is `daemon` for a usable daemon, otherwise the failure: `socket-absent`, `permission-denied` (the file or the connect refused this user), `not-a-socket`, `connect-failed` (socket present, nothing completed the WebSocket upgrade), `handshake-failed` (upgrade or `initialize` failed), `windows-unsupported`, or `bad-response` (reachable, but `initialize` returned something off-schema — `reachable` stays `true`). `schema.compatibility` is `exact` when the daemon reports the pinned version, `unverified` when it differs (methods usually survive upgrades, but the shapes are not re-checked), or `unknown`. `cliVersionProbe` reports whether `codex --version` answered (`ok`, `missing`, `timeout` after 3 s, `error`). The document is always written to stdout and includes `exitCode`; it is `0` only for a usable daemon. From 54017595ab0d374fd22d9b0f43e3e2c1361bfd04 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 01:04:44 +0000 Subject: [PATCH 07/26] feat: deep-read and list via app-server; keep send/wait on CDP Desktop local: maps to bare app-server thread ids. Visible reads stay on CDP; full/deep history uses thread/read (wheel crawl last-resort). List prefers app-server and merges CDP sidebar fields. Send, new-thread-in-project, and wait-for-reply stay CDP-only. Co-authored-by: Zack Jackson --- .changeset/chatgpt-desktop-cdp.md | 2 +- README.md | 2 +- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 411 +++++++++++------ artifact/bin/gbot.mjs | 417 +++++++++++------ artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 433 ++++++++++++------ artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 433 ++++++++++++------ docs/chatgpt-desktop-cdp.md | 61 ++- src/cli/chatgpt-desktop/read.tsx | 2 +- src/cli/chatgpt-desktop/status.tsx | 2 +- src/cli/chatgpt-desktop/threads.tsx | 3 +- .../chatgpt-desktop/app-server-fallback.ts | 242 +++++----- src/core/chatgpt-desktop/cdp-dom.ts | 15 + src/core/chatgpt-desktop/facade.ts | 170 +++++-- src/core/chatgpt-desktop/index.ts | 9 + src/core/chatgpt-desktop/routes.ts | 2 +- src/core/chatgpt-desktop/thread-ids.ts | 63 +++ src/core/chatgpt-desktop/types.ts | 2 + .../tools/chatgpt_desktop_list_threads.tsx | 2 +- .../tools/chatgpt_desktop_read_thread.tsx | 11 +- .../grok-bot/tools/chatgpt_desktop_send.tsx | 2 +- .../grok-bot/tools/chatgpt_desktop_status.tsx | 2 +- .../tools/chatgpt_desktop_wait_reply.tsx | 2 +- tests/route-unit/chatgpt-desktop.test.ts | 366 ++++++++++++--- 25 files changed, 1896 insertions(+), 762 deletions(-) create mode 100644 src/core/chatgpt-desktop/thread-ids.ts diff --git a/.changeset/chatgpt-desktop-cdp.md b/.changeset/chatgpt-desktop-cdp.md index 131bdf3..08dfd6b 100644 --- a/.changeset/chatgpt-desktop-cdp.md +++ b/.changeset/chatgpt-desktop-cdp.md @@ -2,4 +2,4 @@ "grok-bot-cli": minor --- -Scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools (`chatgpt_desktop_*`, `gbot chatgpt-desktop`), with local-only loopback CDP, DOM selectors in one module, and Codex app-server fallback that reports `backend`. +Scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools (`chatgpt_desktop_*`, `gbot chatgpt-desktop`). Visible reads stay on CDP; deep/full history and thread listing prefer the existing Codex app-server client (`local:` ↔ bare thread id), with DOM wheel crawl as last-resort fallback. Send / new-thread / wait stay on CDP. Results report `backend`. diff --git a/README.md b/README.md index f9c5e60..c0074b1 100644 --- a/README.md +++ b/README.md @@ -236,7 +236,7 @@ gbot chatgpt-desktop send --project Launch "hello" gbot chatgpt-desktop send --thread-id "hello" ``` -MCP tools: `chatgpt_desktop_status`, `chatgpt_desktop_list_threads`, `chatgpt_desktop_read_thread`, `chatgpt_desktop_send`, `chatgpt_desktop_wait_reply`. New chats prefer `project` (“Start new chat in …”); `wait_reply` resolves the real conversation id. Default read is visible turns; `--full` wheel-crawls history. List/read/send/wait fall back to the existing Codex app-server client when CDP is down and report `backend: "cdp" | "app-server"`. Details: [docs/chatgpt-desktop-cdp.md](docs/chatgpt-desktop-cdp.md). +MCP tools: `chatgpt_desktop_status`, `chatgpt_desktop_list_threads`, `chatgpt_desktop_read_thread`, `chatgpt_desktop_send`, `chatgpt_desktop_wait_reply`. New chats prefer `project` (“Start new chat in …”); `wait_reply` resolves the real conversation id. Visible/recent reads stay on CDP; `--full` or a limit above the on-screen turns uses the Codex app-server (`thread/read` / resume) — DOM wheel crawl is last-resort only. List prefers app-server and merges CDP sidebar fields (`pinned`/`selected`/`project`). Send / new-thread / wait stay on CDP. Desktop `local:` maps to app-server thread ids. Results report `backend: "cdp" | "app-server"`. Details: [docs/chatgpt-desktop-cdp.md](docs/chatgpt-desktop-cdp.md). **Status contract (`gbot codex status --json`).** `reachable` is endpoint reachability only. `socketState` is `socket`, `absent`, `permission-denied`, or `not-a-socket`; `mode` is `daemon` for a usable daemon, otherwise the failure: `socket-absent`, `permission-denied` (the file or the connect refused this user), `not-a-socket`, `connect-failed` (socket present, nothing completed the WebSocket upgrade), `handshake-failed` (upgrade or `initialize` failed), `windows-unsupported`, or `bad-response` (reachable, but `initialize` returned something off-schema — `reachable` stays `true`). `schema.compatibility` is `exact` when the daemon reports the pinned version, `unverified` when it differs (methods usually survive upgrades, but the shapes are not re-checked), or `unknown`. `cliVersionProbe` reports whether `codex --version` answered (`ok`, `missing`, `timeout` after 3 s, `error`). The document is always written to stdout and includes `exitCode`; it is `0` only for a usable daemon. diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 33c84a2..d7e468b 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"f78f26a4b393e59fb8f9fe2d3fcc5a7decbef73ac76eb9533a1606a8799d3d8d"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"8b3b37f397b7a6d6a65cb480cbee04eb86c5cd6eb3410590ee98d4c6688f8956"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"079ac33ba4d609c7407458d5fb170606801214f13dc8e7c12e543bc276055ec4"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"92f2960c28377bcfbbc44f2f10906e9e02ef8a5d021eb536d74adc05ad12dfb3"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"802e40d8872e9aa4237beb53e0b90047f2e699242153b43220688be49cd8414a"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"e447bd2012a36e0e68c31036d5d95a40216b4194d375c5879b063123f64cc9d5"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"732ae5614b7b68c593f2b43847cb4700581e1dee29cff84306d7c92d5915a636"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"4fc6fde4498e16a5ef22138dc03e8b46f7d42fac4a2aedf63a8f223ddd7d0c7c"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index d49df6d..1536035 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"098bbb556ee7a042e0f284eae7583f832d68926d29970d68fc9de9ddb8750d34","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"d112a572f8a7219a9bc731d0f58f3932b2e8669d42e910acd3962361ec3af32c","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"f4135bee52844417625ab940db9c733d028452dd10b7fd7d3816e7d33563c445"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"315374cf23e0dcdac5207843f0bb8d50198b2191ff33e081f106af1c52f2f556"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"8b3538068d035d1147916a0f43c8cb24a58e98733c624c18e102eee60184d7ac"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"49269496e4dd7866bb7a421aac5743bf929b32bc08ed890188837f43a68f1550"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"fd3c13ab04777bec512e8012d4a3397605719b60887c3d60b24c54c8a2480b57"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"5280b364c75e06e5f00c254f23c21b04144e949590da0c4b02e1c2cbe582aec8"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"cb17b333ac3a50988b6146f6e9b1d76bb2805c8c5073692269f3bd424a504891"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"056613a78d6a247315089c685a0856fd09202fe7cda84c8f3cc892cd04bea521"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"8a45cab48d9f02da4fa2118e0a238696ab2f4ee198faff45ac64580c1f687d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"bd7013ebac4d75e925490fc5fff371f11c87e273c9f0e9530bfb8c306e8afaac"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"56a8ea6c9618831131cdf16bb60e1b0e764a4f8c72c9557d926db94f5b7090b8"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"3a789ff68a7fd4423bc75330e8da671bf781edae1cc131b33f09c5b655d97ae7"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"2ba2372ee09b7e2814e55804907e8659a5c4e518aaa4ded3744c23218e93f30a"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"eb8a53996735657a335b96e6a1f591046aa554d144fdfc12958fbc4e64e59648"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"0e7dd4f7c395805e7071c8188b6fd28452c423b4b8ba341c7b4a8ebb2c5e28a6"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"7dfb0e5cd0117ac38650f83ce257e35f77fe71398b5e5e48c695abbf4d2d7e6c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"7695a3ef40496df91e8d60ba248983c89b1ebdbb3f07e2ec8ffdc2271d33a85d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"50a243585c7e003cb7d2d902a3959ada5129773897901f5253b84aa55ad9652f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"f8db4c6394ff4cf0cbc673468dd16e68365449901e83bd5e9850ce0fa324cb10"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"bb0f72145123dde9bf4438b9f863ddaf4781656972b17f15368c0949145f9c91"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"97e7b53952b5d83d2b0d2f4b0f5576276d6c8bf1310a258a60a6f256ea4443f9"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"56454a78aaea180d78e8cd62385ef66261f1748b593aa5165e587d5975205af4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"ee26dc07b4baade26d8154ed7b4cb69c24285f2997f016bbfb8607e728e7e6bb"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"af5058a1cc68c9d67b940a1943dfa0e9f1988c6f1b37884a4caba352c011f75a"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7bfaf1abfe75bc5c2167d9053c76d33ed830a083780d2dc3017492ec3c44799d"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":21751,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"109855d6f2c090b1edb56b6aac81fabb6cda02a48ef733721707d922e36d6090"},{"bytes":1432235,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"f78f26a4b393e59fb8f9fe2d3fcc5a7decbef73ac76eb9533a1606a8799d3d8d"},{"bytes":2290709,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"8b3b37f397b7a6d6a65cb480cbee04eb86c5cd6eb3410590ee98d4c6688f8956"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1348151,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"079ac33ba4d609c7407458d5fb170606801214f13dc8e7c12e543bc276055ec4"},{"bytes":3174043,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"92f2960c28377bcfbbc44f2f10906e9e02ef8a5d021eb536d74adc05ad12dfb3"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281157,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via CDP. Default: visible turns. --full wheel-crawls history.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","exitCode":"result","options":[{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via CDP. Default: visible turns. --full wheel-crawls history.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, wheel-crawl older history (slow). Default false = visible turns only.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"c90c683bb79425d235dd2c4dd08d0064b2ffad24ceb96adbec8cd26e42eb2784","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend \"cdp\" or \"app-server\".","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Open a ChatGPT Desktop sidebar thread (waits for Loading task… up to openTimeoutMs, default 90s) and harvest turns via local CDP. Default is visible turns only; full=true mouse-wheels the column-reverse timeline for history (skips history-gap placeholders). Falls back to Codex app-server when CDP is unreachable; result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, wheel-crawl older history (slow). Default false = visible turns only.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Falls back to app-server send when CDP is down and threadId is set.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). Falls back to app-server polling when CDP is unreachable.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"933aff6b4167b1601d57c8204e0fa1f7a0ba05fb5836b45ed7e4417c9c10ddbb","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"c69abd855ead0de2b65548933ee22d0581ead66bab93bc3fd75bbc069e75705c","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"3f32dc3e997e0a2a7eae42f11838f7f42c450c70b90a8eda82a7e91c62423e40"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"6ea39a60be58f4080186e3d2713df71b8239d4d109231c3824541bff0b3f5c5f"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"8582da3110017051ec4ca4526dab606311538d14942469e8fad53e4a4c7a3e23"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"e56a9e36bd4211aa3563530e8bbd58ea6aae80734c4fae02d12b4c24e61613eb"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"63201b6028899f4f2b9f63381a8536c5fba09586ea81c8cf857bcaab687e9249"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"cb17b333ac3a50988b6146f6e9b1d76bb2805c8c5073692269f3bd424a504891"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"64af4259dc9be7bdc22224935ab548a51e4e82ccb26a4bb40c39085b9efbda06"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"8a45cab48d9f02da4fa2118e0a238696ab2f4ee198faff45ac64580c1f687d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"98edba7908cecffb141018bc358074f2785baf84bd76c4e9564843d48ad9e2dd"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"56a8ea6c9618831131cdf16bb60e1b0e764a4f8c72c9557d926db94f5b7090b8"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"30bec04c550f1eb9cd09801fc565c341d220e43ffcc134809f7ed69e169f00db"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"f7cd7d29d64677f5222896dbe742afff52644307a787cf4065c3b1acb3cb27b1"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"1e0ae41608486b1950ccf66729f7fce28585a89121606c6bac81485d3dd04f6d"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"9aa8e429ec8e23784d6b5aac62fff893bf24a1b31caea82d0c58ec1553480b76"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"85ea126d588ebd6731fa842df897082fa728bbb93f20efa660e78a133a6eaa36"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"7dfb0e5cd0117ac38650f83ce257e35f77fe71398b5e5e48c695abbf4d2d7e6c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"1c22eddde86abc035751277d75109e4ad8a62941634dd004f313e8ea6e6a688b"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"7d4071ed41a4c0b0814f87bb18d3802235a9c26ad82016b73375aa590f8de8b0"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"7f21f53f2ba99894d65b3dee8518f9483805fc2bda9444939a5a1fa44d74df30"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"56454a78aaea180d78e8cd62385ef66261f1748b593aa5165e587d5975205af4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"ee26dc07b4baade26d8154ed7b4cb69c24285f2997f016bbfb8607e728e7e6bb"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"31e48f236341f3102b94cd35fb2aa406a54a56cd86b2006452ec569ad503640d"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7bfaf1abfe75bc5c2167d9053c76d33ed830a083780d2dc3017492ec3c44799d"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":21751,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"e6212f639e4817cd0294212f671bab2a604ec4eaede4b20e6e25cc08c2b26bfd"},{"bytes":1439316,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"802e40d8872e9aa4237beb53e0b90047f2e699242153b43220688be49cd8414a"},{"bytes":2297844,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"e447bd2012a36e0e68c31036d5d95a40216b4194d375c5879b063123f64cc9d5"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1355572,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"732ae5614b7b68c593f2b43847cb4700581e1dee29cff84306d7c92d5915a636"},{"bytes":3181472,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"4fc6fde4498e16a5ef22138dc03e8b46f7d42fac4a2aedf63a8f223ddd7d0c7c"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281157,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread. Visible turns via CDP; --full / deep history via app-server (wheel crawl last-resort).","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.","exitCode":"result","options":[{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread. Visible turns via CDP; --full / deep history via app-server (wheel crawl last-resort).","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"528b746c2d3913bf33a1fbee1d999fc136647113ac4f8eb4505d0ba384cfddd6","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via the Codex app-server when available (thread/list), merging CDP-only sidebar fields (pinned, selected, project, kind) when CDP is connected. Desktop local: maps to bare app-server ids. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread. Visible/recent turns use local CDP DOM harvest. full=true or a limit above the on-screen turns uses the Codex app-server (thread/read / resume); Desktop local: maps to the bare app-server id. DOM wheel crawl is only a fallback when app-server misses the thread. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index 4bd9752..b8ba2b1 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -8616,7 +8616,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Read a ChatGPT Desktop thread via CDP. Default: visible turns. --full wheel-crawls history.', + description: 'Read a ChatGPT Desktop thread. Visible turns via CDP; --full / deep history via app-server (wheel crawl last-resort).', exitCode: 'result', positionals: [ 'threadId' @@ -8765,7 +8765,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.', + description: 'Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, @@ -8805,7 +8805,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).', + description: 'List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, @@ -11130,6 +11130,7 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/app-server-fallback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); + var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); async function appServerListThreads({ limit = 50 } = {}) { const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit @@ -11137,117 +11138,71 @@ var __webpack_modules__ = { return { backend: 'app-server', limit: out.limit, - threads: out.threads.map((thread)=>({ - threadId: String(thread.id ?? ''), + threads: out.threads.map((thread)=>{ + const bare = String(thread.id ?? ''); + return { + threadId: bare ? (0, _thread_ids_js__rspack_import_1.BS)(bare) : '', title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), pinned: false, selected: false, kind: 'codex' - })) + }; + }) }; } async function appServerReadThread({ threadId, limit = 100, full = false }) { + const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); + if (candidates.length === 0) { + throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); + } const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { - let turns = []; - try { - const read = await client.request('thread/read', { - threadId - }); - const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - turns = normalizeTurns(raw).slice(full ? 0 : -limit); - if (full && limit > 0) turns = turns.slice(0, limit); - else if (!full) turns = turns.slice(-limit); - } catch { - const items = await client.request('thread/items/list', { - threadId, - limit: Math.min(limit, 100) - }); - turns = normalizeTurns(items.data ?? []).slice(-limit); + let lastError; + for (const candidate of candidates){ + try { + const turns = await readTurnsForId(client, candidate, { + limit, + full + }); + return { + threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), + turns, + backend: 'app-server', + limit, + full + }; + } catch (error) { + lastError = error; + } } - return { - threadId, - turns, - backend: 'app-server', - limit, - full - }; + throw lastError instanceof Error ? lastError : new Error(`app-server thread read failed for ${threadId}`); } finally{ client.close(); } } - async function appServerSendMessage({ threadId, text }) { - if (!threadId) { - return { - threadId: 'new', - backend: 'app-server', - experimental: false, - delivery: 'rejected', - message: 'app-server fallback requires an existing threadId; starting a new Desktop thread needs CDP' - }; - } - const receipt = await (0, _codex_bridge_js__rspack_import_0.ZS)(threadId, text); - return { - threadId, - backend: 'app-server', - experimental: false, - delivery: receipt.delivery ?? 'accepted', - message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined - }; - } - async function appServerWaitForReply({ threadId = 'unknown', timeoutMs = 60000 }) { - if (!threadId || threadId === 'unknown' || threadId === 'new') { - return { - threadId: threadId || 'unknown', - reply: '', - backend: 'app-server', - experimental: false, - delivery: 'rejected' - }; - } - const baseline = await appServerReadThread({ - threadId, - limit: 200 - }); - const seen = new Set(baseline.turns.map((turn)=>turn.turnKey)); - const deadline = Date.now() + timeoutMs; - while(Date.now() < deadline){ - await new Promise((resolve)=>setTimeout(resolve, 400)); - const page = await appServerReadThread({ - threadId, - limit: 200 - }); - const fresh = page.turns.filter((turn)=>!seen.has(turn.turnKey) && turn.role === 'assistant' && turn.text); - const reply = fresh.at(-1)?.text ?? ''; - if (reply) { - return { - threadId, - reply, - backend: 'app-server', - experimental: false, - delivery: 'replied' - }; - } - } - return { - threadId, - reply: '', - backend: 'app-server', - experimental: false, - delivery: 'timeout' - }; - } async function appServerOpenThread(threadId) { + const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); + if (candidates.length === 0) { + throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); + } const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { - await client.request('thread/resume', { - threadId, - excludeTurns: true - }); - return { - threadId, - backend: 'app-server' - }; + let lastError; + for (const candidate of candidates){ + try { + await client.request('thread/resume', { + threadId: candidate, + excludeTurns: true + }); + return { + threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), + backend: 'app-server' + }; + } catch (error) { + lastError = error; + } + } + throw lastError instanceof Error ? lastError : new Error(`app-server thread/resume failed for ${threadId}`); } finally{ client.close(); } @@ -11260,6 +11215,68 @@ var __webpack_modules__ = { socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined }; } + async function readTurnsForId(client, threadId, { limit, full }) { + try { + const read = await client.request('thread/read', { + threadId + }); + const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; + if (Array.isArray(raw) && raw.length > 0) { + return sliceTurns(normalizeTurns(raw), { + limit, + full + }); + } + } catch {} + try { + const resumed = await client.request('thread/resume', { + threadId, + excludeTurns: false + }); + const raw = resumed.thread?.turns ?? resumed.turns ?? resumed.thread?.items ?? []; + if (Array.isArray(raw) && raw.length > 0) { + return sliceTurns(normalizeTurns(raw), { + limit, + full + }); + } + } catch {} + for (const method of [ + 'thread/turns/list', + 'thread/items/list' + ]){ + try { + const collected = []; + let cursor; + for(let page = 0; page < 20; page++){ + const result = await client.request(method, { + threadId, + limit: 100, + ...cursor ? { + cursor + } : {} + }); + if (!Array.isArray(result.data)) break; + collected.push(...result.data); + if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; + cursor = result.nextCursor; + if (!full && collected.length >= limit) break; + } + if (collected.length > 0) { + return sliceTurns(normalizeTurns(collected), { + limit, + full + }); + } + } catch {} + } + throw new Error(`app-server has no turn history for thread ${threadId}`); + } + function sliceTurns(turns, { limit, full }) { + if (limit <= 0) return turns; + if (full) return turns.slice(0, limit); + return turns.slice(-limit); + } function normalizeTurns(raw) { const turns = []; for (const [index, item] of raw.entries()){ @@ -11279,10 +11296,8 @@ var __webpack_modules__ = { return turns; } __webpack_require__.d(__webpack_exports__, { - Ab: ()=>appServerSendMessage, Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, - bk: ()=>appServerWaitForReply, dM: ()=>appServerStatusProbe, zu: ()=>appServerOpenThread }); @@ -11584,6 +11599,18 @@ var __webpack_modules__ = { return out; } const LIST_THREADS_EXPRESSION = `(() => { + const skipProjectLabels = new Set(['Recent', 'Pinned', 'Threads', 'Chats']); + const projectFor = (row) => { + let el = row.parentElement; + for (let i = 0; i < 8 && el; i += 1, el = el.parentElement) { + const attr = + el.getAttribute('data-app-action-sidebar-project') || + el.getAttribute('data-app-action-sidebar-project-name') || + el.getAttribute('data-app-action-sidebar-section-title'); + if (attr && !skipProjectLabels.has(attr)) return attr; + } + return undefined; + }; const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); const seen = new Set(); const out = []; @@ -11591,12 +11618,14 @@ var __webpack_modules__ = { const threadId = row.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''; if (!threadId || seen.has(threadId)) continue; seen.add(threadId); + const project = projectFor(row); out.push({ threadId, title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + ...(project ? { project } : {}), }); } return out; @@ -11734,7 +11763,10 @@ var __webpack_modules__ = { title: String(row.title ?? ''), pinned: Boolean(row.pinned), selected: Boolean(row.selected), - kind: String(row.kind ?? 'unknown') + kind: String(row.kind ?? 'unknown'), + ...row.project ? { + project: String(row.project) + } : {} })); } async function openThreadInDom(session, sessionId, threadId) { @@ -12150,11 +12182,10 @@ var __webpack_modules__ = { var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, readThread: _app_server_fallback_js__rspack_import_1.Jf, - sendMessage: _app_server_fallback_js__rspack_import_1.Ab, - waitForReply: _app_server_fallback_js__rspack_import_1.bk, openThread: _app_server_fallback_js__rspack_import_1.zu, statusProbe: _app_server_fallback_js__rspack_import_1.dM }; @@ -12185,44 +12216,83 @@ var __webpack_modules__ = { return this.#cdp.listTargets(); } async listThreads(options) { + let appList = null; + let appError; try { - await this.#ensureCdp(); - return await this.#cdp.listThreads(options); + appList = await this.#fallbacks.listThreads(options); } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.listThreads(options); + appError = error; } - } - async readThread(options) { + let cdpList = null; + let cdpError; try { await this.#ensureCdp(); - return await this.#cdp.readThread(options); + cdpList = await this.#cdp.listThreads(options); } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.readThread(options); + if (isCdpFailure(error)) { + this.#cdpConnected = false; + } else { + cdpError = error; + } } - } - async sendMessage(options) { - try { - await this.#ensureCdp(); - return await this.#cdp.sendMessage(options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.sendMessage(options); + if (appList && cdpList) { + return mergeThreadLists(appList, cdpList); } + if (appList) return appList; + if (cdpList) return cdpList; + if (cdpError) throw cdpError; + if (appError) throw appError; + throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); } - async waitForReply(options) { + async readThread(options) { + const limit = options.limit ?? 100; + const full = options.full ?? false; + const cdpConnected = await this.#tryEnsureCdp(); + if ((0, _thread_ids_js__rspack_import_4.vr)(options.threadId)) { + if (!cdpConnected) { + throw new _errors_js__rspack_import_2.sO(`ChatGPT Desktop temporary thread ${options.threadId} requires CDP`); + } + return this.#cdp.readThread({ + ...options, + limit, + full + }); + } + if (cdpConnected && !full) { + const visible = await this.#cdp.readThread({ + ...options, + limit, + full: false + }); + if (limit <= visible.turns.length) { + return visible; + } + } try { - await this.#ensureCdp(); - return await this.#cdp.waitForReply(options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.waitForReply({ - threadId: options.threadId ?? 'unknown', - timeoutMs: options.timeoutMs + return await this.#fallbacks.readThread({ + threadId: options.threadId, + limit, + full }); + } catch (appError) { + if (cdpConnected) { + return this.#cdp.readThread({ + ...options, + limit, + full: true + }); + } + throw appError; } } + async sendMessage(options) { + await this.#ensureCdp(); + return this.#cdp.sendMessage(options); + } + async waitForReply(options) { + await this.#ensureCdp(); + return this.#cdp.waitForReply(options); + } async openThread(threadId, options) { try { await this.#ensureCdp(); @@ -12248,7 +12318,7 @@ var __webpack_modules__ = { port: this.#port, appServerFallback, reachable, - message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server fallback is available' : cdpStatus.message, + message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/deep-read' : cdpStatus.message, exitCode: reachable ? 0 : 1 }; } @@ -12263,6 +12333,47 @@ var __webpack_modules__ = { }); this.#cdpConnected = true; } + async #tryEnsureCdp() { + try { + await this.#ensureCdp(); + return true; + } catch (error) { + if (!isCdpFailure(error)) throw error; + this.#cdpConnected = false; + return false; + } + } + } + function mergeThreadLists(appList, cdpList) { + const cdpByKey = new Map(); + for (const thread of cdpList.threads){ + const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + cdpByKey.set(key, thread); + } + const merged = appList.threads.map((thread)=>{ + const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + const cdp = cdpByKey.get(key); + if (!cdp) return thread; + return { + ...thread, + title: thread.title || cdp.title, + pinned: cdp.pinned, + selected: cdp.selected, + kind: cdp.kind || thread.kind, + ...cdp.project !== undefined ? { + project: cdp.project + } : {} + }; + }); + for (const thread of cdpList.threads){ + if (merged.some((row)=>(0, _thread_ids_js__rspack_import_4.LV)(row.threadId, thread.threadId))) continue; + merged.push(thread); + } + return { + backend: 'app-server', + limit: appList.limit, + threads: merged.slice(0, appList.limit) + }; } function isCdpFailure(error) { if (error instanceof _errors_js__rspack_import_2.sO) return true; @@ -12519,6 +12630,50 @@ var __webpack_modules__ = { FD: resultSchema }); }, + "./src/core/chatgpt-desktop/thread-ids.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _cdp_dom_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); + const LOCAL_THREAD_ID_PREFIX = 'local:'; + function isTemporaryDesktopThreadId(threadId) { + return threadId.startsWith(_cdp_dom_js__rspack_import_0.hA); + } + function toAppServerThreadId(threadId) { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return null; + if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) { + const bare = threadId.slice(LOCAL_THREAD_ID_PREFIX.length); + return bare || null; + } + return threadId; + } + function toDesktopThreadId(threadId) { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return threadId; + if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) return threadId; + return `${LOCAL_THREAD_ID_PREFIX}${threadId}`; + } + function threadIdsEquivalent(a, b) { + const left = toAppServerThreadId(a) ?? a; + const right = toAppServerThreadId(b) ?? b; + return left === right; + } + function appServerThreadIdCandidates(threadId) { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return []; + const bare = toAppServerThreadId(threadId); + const out = []; + const push = (id)=>{ + if (id && !out.includes(id)) out.push(id); + }; + push(bare); + push(threadId); + if (bare) push(toDesktopThreadId(bare)); + return out; + } + __webpack_require__.d(__webpack_exports__, { + BS: ()=>toDesktopThreadId, + EJ: ()=>appServerThreadIdCandidates, + LV: ()=>threadIdsEquivalent, + nn: ()=>toAppServerThreadId, + vr: ()=>isTemporaryDesktopThreadId + }); + }, "./src/core/claude-routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_1 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _claude_channel_js__rspack_import_0 = __webpack_require__("./src/core/claude-channel.js"); diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index 6548ed9..e262de1 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -7024,7 +7024,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Read a ChatGPT Desktop thread via CDP. Default: visible turns. --full wheel-crawls history.', + description: 'Read a ChatGPT Desktop thread. Visible turns via CDP; --full / deep history via app-server (wheel crawl last-resort).', exitCode: 'result', positionals: [ 'threadId' @@ -7173,7 +7173,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.', + description: 'Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, @@ -7213,7 +7213,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).', + description: 'List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, @@ -9538,6 +9538,7 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/app-server-fallback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); + var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); async function appServerListThreads({ limit = 50 } = {}) { const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit @@ -9545,117 +9546,71 @@ var __webpack_modules__ = { return { backend: 'app-server', limit: out.limit, - threads: out.threads.map((thread)=>({ - threadId: String(thread.id ?? ''), + threads: out.threads.map((thread)=>{ + const bare = String(thread.id ?? ''); + return { + threadId: bare ? (0, _thread_ids_js__rspack_import_1.BS)(bare) : '', title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), pinned: false, selected: false, kind: 'codex' - })) + }; + }) }; } async function appServerReadThread({ threadId, limit = 100, full = false }) { + const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); + if (candidates.length === 0) { + throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); + } const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { - let turns = []; - try { - const read = await client.request('thread/read', { - threadId - }); - const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - turns = normalizeTurns(raw).slice(full ? 0 : -limit); - if (full && limit > 0) turns = turns.slice(0, limit); - else if (!full) turns = turns.slice(-limit); - } catch { - const items = await client.request('thread/items/list', { - threadId, - limit: Math.min(limit, 100) - }); - turns = normalizeTurns(items.data ?? []).slice(-limit); + let lastError; + for (const candidate of candidates){ + try { + const turns = await readTurnsForId(client, candidate, { + limit, + full + }); + return { + threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), + turns, + backend: 'app-server', + limit, + full + }; + } catch (error) { + lastError = error; + } } - return { - threadId, - turns, - backend: 'app-server', - limit, - full - }; + throw lastError instanceof Error ? lastError : new Error(`app-server thread read failed for ${threadId}`); } finally{ client.close(); } } - async function appServerSendMessage({ threadId, text }) { - if (!threadId) { - return { - threadId: 'new', - backend: 'app-server', - experimental: false, - delivery: 'rejected', - message: 'app-server fallback requires an existing threadId; starting a new Desktop thread needs CDP' - }; - } - const receipt = await (0, _codex_bridge_js__rspack_import_0.ZS)(threadId, text); - return { - threadId, - backend: 'app-server', - experimental: false, - delivery: receipt.delivery ?? 'accepted', - message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined - }; - } - async function appServerWaitForReply({ threadId = 'unknown', timeoutMs = 60000 }) { - if (!threadId || threadId === 'unknown' || threadId === 'new') { - return { - threadId: threadId || 'unknown', - reply: '', - backend: 'app-server', - experimental: false, - delivery: 'rejected' - }; - } - const baseline = await appServerReadThread({ - threadId, - limit: 200 - }); - const seen = new Set(baseline.turns.map((turn)=>turn.turnKey)); - const deadline = Date.now() + timeoutMs; - while(Date.now() < deadline){ - await new Promise((resolve)=>setTimeout(resolve, 400)); - const page = await appServerReadThread({ - threadId, - limit: 200 - }); - const fresh = page.turns.filter((turn)=>!seen.has(turn.turnKey) && turn.role === 'assistant' && turn.text); - const reply = fresh.at(-1)?.text ?? ''; - if (reply) { - return { - threadId, - reply, - backend: 'app-server', - experimental: false, - delivery: 'replied' - }; - } - } - return { - threadId, - reply: '', - backend: 'app-server', - experimental: false, - delivery: 'timeout' - }; - } async function appServerOpenThread(threadId) { + const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); + if (candidates.length === 0) { + throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); + } const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { - await client.request('thread/resume', { - threadId, - excludeTurns: true - }); - return { - threadId, - backend: 'app-server' - }; + let lastError; + for (const candidate of candidates){ + try { + await client.request('thread/resume', { + threadId: candidate, + excludeTurns: true + }); + return { + threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), + backend: 'app-server' + }; + } catch (error) { + lastError = error; + } + } + throw lastError instanceof Error ? lastError : new Error(`app-server thread/resume failed for ${threadId}`); } finally{ client.close(); } @@ -9668,6 +9623,68 @@ var __webpack_modules__ = { socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined }; } + async function readTurnsForId(client, threadId, { limit, full }) { + try { + const read = await client.request('thread/read', { + threadId + }); + const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; + if (Array.isArray(raw) && raw.length > 0) { + return sliceTurns(normalizeTurns(raw), { + limit, + full + }); + } + } catch {} + try { + const resumed = await client.request('thread/resume', { + threadId, + excludeTurns: false + }); + const raw = resumed.thread?.turns ?? resumed.turns ?? resumed.thread?.items ?? []; + if (Array.isArray(raw) && raw.length > 0) { + return sliceTurns(normalizeTurns(raw), { + limit, + full + }); + } + } catch {} + for (const method of [ + 'thread/turns/list', + 'thread/items/list' + ]){ + try { + const collected = []; + let cursor; + for(let page = 0; page < 20; page++){ + const result = await client.request(method, { + threadId, + limit: 100, + ...cursor ? { + cursor + } : {} + }); + if (!Array.isArray(result.data)) break; + collected.push(...result.data); + if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; + cursor = result.nextCursor; + if (!full && collected.length >= limit) break; + } + if (collected.length > 0) { + return sliceTurns(normalizeTurns(collected), { + limit, + full + }); + } + } catch {} + } + throw new Error(`app-server has no turn history for thread ${threadId}`); + } + function sliceTurns(turns, { limit, full }) { + if (limit <= 0) return turns; + if (full) return turns.slice(0, limit); + return turns.slice(-limit); + } function normalizeTurns(raw) { const turns = []; for (const [index, item] of raw.entries()){ @@ -9687,10 +9704,8 @@ var __webpack_modules__ = { return turns; } __webpack_require__.d(__webpack_exports__, { - Ab: ()=>appServerSendMessage, Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, - bk: ()=>appServerWaitForReply, dM: ()=>appServerStatusProbe, zu: ()=>appServerOpenThread }); @@ -9992,6 +10007,18 @@ var __webpack_modules__ = { return out; } const LIST_THREADS_EXPRESSION = `(() => { + const skipProjectLabels = new Set(['Recent', 'Pinned', 'Threads', 'Chats']); + const projectFor = (row) => { + let el = row.parentElement; + for (let i = 0; i < 8 && el; i += 1, el = el.parentElement) { + const attr = + el.getAttribute('data-app-action-sidebar-project') || + el.getAttribute('data-app-action-sidebar-project-name') || + el.getAttribute('data-app-action-sidebar-section-title'); + if (attr && !skipProjectLabels.has(attr)) return attr; + } + return undefined; + }; const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); const seen = new Set(); const out = []; @@ -9999,12 +10026,14 @@ var __webpack_modules__ = { const threadId = row.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''; if (!threadId || seen.has(threadId)) continue; seen.add(threadId); + const project = projectFor(row); out.push({ threadId, title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + ...(project ? { project } : {}), }); } return out; @@ -10142,7 +10171,10 @@ var __webpack_modules__ = { title: String(row.title ?? ''), pinned: Boolean(row.pinned), selected: Boolean(row.selected), - kind: String(row.kind ?? 'unknown') + kind: String(row.kind ?? 'unknown'), + ...row.project ? { + project: String(row.project) + } : {} })); } async function openThreadInDom(session, sessionId, threadId) { @@ -10558,11 +10590,10 @@ var __webpack_modules__ = { var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, readThread: _app_server_fallback_js__rspack_import_1.Jf, - sendMessage: _app_server_fallback_js__rspack_import_1.Ab, - waitForReply: _app_server_fallback_js__rspack_import_1.bk, openThread: _app_server_fallback_js__rspack_import_1.zu, statusProbe: _app_server_fallback_js__rspack_import_1.dM }; @@ -10593,44 +10624,83 @@ var __webpack_modules__ = { return this.#cdp.listTargets(); } async listThreads(options) { + let appList = null; + let appError; try { - await this.#ensureCdp(); - return await this.#cdp.listThreads(options); + appList = await this.#fallbacks.listThreads(options); } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.listThreads(options); + appError = error; } - } - async readThread(options) { + let cdpList = null; + let cdpError; try { await this.#ensureCdp(); - return await this.#cdp.readThread(options); + cdpList = await this.#cdp.listThreads(options); } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.readThread(options); + if (isCdpFailure(error)) { + this.#cdpConnected = false; + } else { + cdpError = error; + } } - } - async sendMessage(options) { - try { - await this.#ensureCdp(); - return await this.#cdp.sendMessage(options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.sendMessage(options); + if (appList && cdpList) { + return mergeThreadLists(appList, cdpList); } + if (appList) return appList; + if (cdpList) return cdpList; + if (cdpError) throw cdpError; + if (appError) throw appError; + throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); } - async waitForReply(options) { + async readThread(options) { + const limit = options.limit ?? 100; + const full = options.full ?? false; + const cdpConnected = await this.#tryEnsureCdp(); + if ((0, _thread_ids_js__rspack_import_4.vr)(options.threadId)) { + if (!cdpConnected) { + throw new _errors_js__rspack_import_2.sO(`ChatGPT Desktop temporary thread ${options.threadId} requires CDP`); + } + return this.#cdp.readThread({ + ...options, + limit, + full + }); + } + if (cdpConnected && !full) { + const visible = await this.#cdp.readThread({ + ...options, + limit, + full: false + }); + if (limit <= visible.turns.length) { + return visible; + } + } try { - await this.#ensureCdp(); - return await this.#cdp.waitForReply(options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.waitForReply({ - threadId: options.threadId ?? 'unknown', - timeoutMs: options.timeoutMs + return await this.#fallbacks.readThread({ + threadId: options.threadId, + limit, + full }); + } catch (appError) { + if (cdpConnected) { + return this.#cdp.readThread({ + ...options, + limit, + full: true + }); + } + throw appError; } } + async sendMessage(options) { + await this.#ensureCdp(); + return this.#cdp.sendMessage(options); + } + async waitForReply(options) { + await this.#ensureCdp(); + return this.#cdp.waitForReply(options); + } async openThread(threadId, options) { try { await this.#ensureCdp(); @@ -10656,7 +10726,7 @@ var __webpack_modules__ = { port: this.#port, appServerFallback, reachable, - message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server fallback is available' : cdpStatus.message, + message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/deep-read' : cdpStatus.message, exitCode: reachable ? 0 : 1 }; } @@ -10671,6 +10741,47 @@ var __webpack_modules__ = { }); this.#cdpConnected = true; } + async #tryEnsureCdp() { + try { + await this.#ensureCdp(); + return true; + } catch (error) { + if (!isCdpFailure(error)) throw error; + this.#cdpConnected = false; + return false; + } + } + } + function mergeThreadLists(appList, cdpList) { + const cdpByKey = new Map(); + for (const thread of cdpList.threads){ + const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + cdpByKey.set(key, thread); + } + const merged = appList.threads.map((thread)=>{ + const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + const cdp = cdpByKey.get(key); + if (!cdp) return thread; + return { + ...thread, + title: thread.title || cdp.title, + pinned: cdp.pinned, + selected: cdp.selected, + kind: cdp.kind || thread.kind, + ...cdp.project !== undefined ? { + project: cdp.project + } : {} + }; + }); + for (const thread of cdpList.threads){ + if (merged.some((row)=>(0, _thread_ids_js__rspack_import_4.LV)(row.threadId, thread.threadId))) continue; + merged.push(thread); + } + return { + backend: 'app-server', + limit: appList.limit, + threads: merged.slice(0, appList.limit) + }; } function isCdpFailure(error) { if (error instanceof _errors_js__rspack_import_2.sO) return true; @@ -10927,6 +11038,50 @@ var __webpack_modules__ = { FD: resultSchema }); }, + "./src/core/chatgpt-desktop/thread-ids.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _cdp_dom_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); + const LOCAL_THREAD_ID_PREFIX = 'local:'; + function isTemporaryDesktopThreadId(threadId) { + return threadId.startsWith(_cdp_dom_js__rspack_import_0.hA); + } + function toAppServerThreadId(threadId) { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return null; + if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) { + const bare = threadId.slice(LOCAL_THREAD_ID_PREFIX.length); + return bare || null; + } + return threadId; + } + function toDesktopThreadId(threadId) { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return threadId; + if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) return threadId; + return `${LOCAL_THREAD_ID_PREFIX}${threadId}`; + } + function threadIdsEquivalent(a, b) { + const left = toAppServerThreadId(a) ?? a; + const right = toAppServerThreadId(b) ?? b; + return left === right; + } + function appServerThreadIdCandidates(threadId) { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return []; + const bare = toAppServerThreadId(threadId); + const out = []; + const push = (id)=>{ + if (id && !out.includes(id)) out.push(id); + }; + push(bare); + push(threadId); + if (bare) push(toDesktopThreadId(bare)); + return out; + } + __webpack_require__.d(__webpack_exports__, { + BS: ()=>toDesktopThreadId, + EJ: ()=>appServerThreadIdCandidates, + LV: ()=>threadIdsEquivalent, + nn: ()=>toAppServerThreadId, + vr: ()=>isTemporaryDesktopThreadId + }); + }, "./src/core/claude-routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_1 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _claude_channel_js__rspack_import_0 = __webpack_require__("./src/core/claude-channel.js"); @@ -39147,7 +39302,7 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "Read a ChatGPT Desktop thread via CDP. Default: visible turns. --full wheel-crawls history.", + "description": "Read a ChatGPT Desktop thread. Visible turns via CDP; --full / deep history via app-server (wheel crawl last-resort).", "exitCode": "result", "options": [ { @@ -39254,7 +39409,7 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.", + "description": "Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.", "exitCode": "result", "options": [ { @@ -39275,7 +39430,7 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).", + "description": "List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.", "exitCode": "result", "options": [ { diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index a001f21..a16c2ae 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8086,6 +8086,7 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/app-server-fallback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); + var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); async function appServerListThreads({ limit = 50 } = {}) { const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit @@ -8093,117 +8094,71 @@ var __webpack_modules__ = { return { backend: 'app-server', limit: out.limit, - threads: out.threads.map((thread)=>({ - threadId: String(thread.id ?? ''), + threads: out.threads.map((thread)=>{ + const bare = String(thread.id ?? ''); + return { + threadId: bare ? (0, _thread_ids_js__rspack_import_1.BS)(bare) : '', title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), pinned: false, selected: false, kind: 'codex' - })) + }; + }) }; } async function appServerReadThread({ threadId, limit = 100, full = false }) { + const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); + if (candidates.length === 0) { + throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); + } const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { - let turns = []; - try { - const read = await client.request('thread/read', { - threadId - }); - const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - turns = normalizeTurns(raw).slice(full ? 0 : -limit); - if (full && limit > 0) turns = turns.slice(0, limit); - else if (!full) turns = turns.slice(-limit); - } catch { - const items = await client.request('thread/items/list', { - threadId, - limit: Math.min(limit, 100) - }); - turns = normalizeTurns(items.data ?? []).slice(-limit); + let lastError; + for (const candidate of candidates){ + try { + const turns = await readTurnsForId(client, candidate, { + limit, + full + }); + return { + threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), + turns, + backend: 'app-server', + limit, + full + }; + } catch (error) { + lastError = error; + } } - return { - threadId, - turns, - backend: 'app-server', - limit, - full - }; + throw lastError instanceof Error ? lastError : new Error(`app-server thread read failed for ${threadId}`); } finally{ client.close(); } } - async function appServerSendMessage({ threadId, text }) { - if (!threadId) { - return { - threadId: 'new', - backend: 'app-server', - experimental: false, - delivery: 'rejected', - message: 'app-server fallback requires an existing threadId; starting a new Desktop thread needs CDP' - }; - } - const receipt = await (0, _codex_bridge_js__rspack_import_0.ZS)(threadId, text); - return { - threadId, - backend: 'app-server', - experimental: false, - delivery: receipt.delivery ?? 'accepted', - message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined - }; - } - async function appServerWaitForReply({ threadId = 'unknown', timeoutMs = 60000 }) { - if (!threadId || threadId === 'unknown' || threadId === 'new') { - return { - threadId: threadId || 'unknown', - reply: '', - backend: 'app-server', - experimental: false, - delivery: 'rejected' - }; - } - const baseline = await appServerReadThread({ - threadId, - limit: 200 - }); - const seen = new Set(baseline.turns.map((turn)=>turn.turnKey)); - const deadline = Date.now() + timeoutMs; - while(Date.now() < deadline){ - await new Promise((resolve)=>setTimeout(resolve, 400)); - const page = await appServerReadThread({ - threadId, - limit: 200 - }); - const fresh = page.turns.filter((turn)=>!seen.has(turn.turnKey) && turn.role === 'assistant' && turn.text); - const reply = fresh.at(-1)?.text ?? ''; - if (reply) { - return { - threadId, - reply, - backend: 'app-server', - experimental: false, - delivery: 'replied' - }; - } - } - return { - threadId, - reply: '', - backend: 'app-server', - experimental: false, - delivery: 'timeout' - }; - } async function appServerOpenThread(threadId) { + const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); + if (candidates.length === 0) { + throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); + } const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { - await client.request('thread/resume', { - threadId, - excludeTurns: true - }); - return { - threadId, - backend: 'app-server' - }; + let lastError; + for (const candidate of candidates){ + try { + await client.request('thread/resume', { + threadId: candidate, + excludeTurns: true + }); + return { + threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), + backend: 'app-server' + }; + } catch (error) { + lastError = error; + } + } + throw lastError instanceof Error ? lastError : new Error(`app-server thread/resume failed for ${threadId}`); } finally{ client.close(); } @@ -8216,6 +8171,68 @@ var __webpack_modules__ = { socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined }; } + async function readTurnsForId(client, threadId, { limit, full }) { + try { + const read = await client.request('thread/read', { + threadId + }); + const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; + if (Array.isArray(raw) && raw.length > 0) { + return sliceTurns(normalizeTurns(raw), { + limit, + full + }); + } + } catch {} + try { + const resumed = await client.request('thread/resume', { + threadId, + excludeTurns: false + }); + const raw = resumed.thread?.turns ?? resumed.turns ?? resumed.thread?.items ?? []; + if (Array.isArray(raw) && raw.length > 0) { + return sliceTurns(normalizeTurns(raw), { + limit, + full + }); + } + } catch {} + for (const method of [ + 'thread/turns/list', + 'thread/items/list' + ]){ + try { + const collected = []; + let cursor; + for(let page = 0; page < 20; page++){ + const result = await client.request(method, { + threadId, + limit: 100, + ...cursor ? { + cursor + } : {} + }); + if (!Array.isArray(result.data)) break; + collected.push(...result.data); + if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; + cursor = result.nextCursor; + if (!full && collected.length >= limit) break; + } + if (collected.length > 0) { + return sliceTurns(normalizeTurns(collected), { + limit, + full + }); + } + } catch {} + } + throw new Error(`app-server has no turn history for thread ${threadId}`); + } + function sliceTurns(turns, { limit, full }) { + if (limit <= 0) return turns; + if (full) return turns.slice(0, limit); + return turns.slice(-limit); + } function normalizeTurns(raw) { const turns = []; for (const [index, item] of raw.entries()){ @@ -8235,10 +8252,8 @@ var __webpack_modules__ = { return turns; } __webpack_require__.d(__webpack_exports__, { - Ab: ()=>appServerSendMessage, Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, - bk: ()=>appServerWaitForReply, dM: ()=>appServerStatusProbe, zu: ()=>appServerOpenThread }); @@ -8540,6 +8555,18 @@ var __webpack_modules__ = { return out; } const LIST_THREADS_EXPRESSION = `(() => { + const skipProjectLabels = new Set(['Recent', 'Pinned', 'Threads', 'Chats']); + const projectFor = (row) => { + let el = row.parentElement; + for (let i = 0; i < 8 && el; i += 1, el = el.parentElement) { + const attr = + el.getAttribute('data-app-action-sidebar-project') || + el.getAttribute('data-app-action-sidebar-project-name') || + el.getAttribute('data-app-action-sidebar-section-title'); + if (attr && !skipProjectLabels.has(attr)) return attr; + } + return undefined; + }; const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); const seen = new Set(); const out = []; @@ -8547,12 +8574,14 @@ var __webpack_modules__ = { const threadId = row.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''; if (!threadId || seen.has(threadId)) continue; seen.add(threadId); + const project = projectFor(row); out.push({ threadId, title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + ...(project ? { project } : {}), }); } return out; @@ -8690,7 +8719,10 @@ var __webpack_modules__ = { title: String(row.title ?? ''), pinned: Boolean(row.pinned), selected: Boolean(row.selected), - kind: String(row.kind ?? 'unknown') + kind: String(row.kind ?? 'unknown'), + ...row.project ? { + project: String(row.project) + } : {} })); } async function openThreadInDom(session, sessionId, threadId) { @@ -9106,11 +9138,10 @@ var __webpack_modules__ = { var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, readThread: _app_server_fallback_js__rspack_import_1.Jf, - sendMessage: _app_server_fallback_js__rspack_import_1.Ab, - waitForReply: _app_server_fallback_js__rspack_import_1.bk, openThread: _app_server_fallback_js__rspack_import_1.zu, statusProbe: _app_server_fallback_js__rspack_import_1.dM }; @@ -9141,44 +9172,83 @@ var __webpack_modules__ = { return this.#cdp.listTargets(); } async listThreads(options) { + let appList = null; + let appError; try { - await this.#ensureCdp(); - return await this.#cdp.listThreads(options); + appList = await this.#fallbacks.listThreads(options); } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.listThreads(options); + appError = error; } - } - async readThread(options) { + let cdpList = null; + let cdpError; try { await this.#ensureCdp(); - return await this.#cdp.readThread(options); + cdpList = await this.#cdp.listThreads(options); } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.readThread(options); + if (isCdpFailure(error)) { + this.#cdpConnected = false; + } else { + cdpError = error; + } } - } - async sendMessage(options) { - try { - await this.#ensureCdp(); - return await this.#cdp.sendMessage(options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.sendMessage(options); + if (appList && cdpList) { + return mergeThreadLists(appList, cdpList); } + if (appList) return appList; + if (cdpList) return cdpList; + if (cdpError) throw cdpError; + if (appError) throw appError; + throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); } - async waitForReply(options) { + async readThread(options) { + const limit = options.limit ?? 100; + const full = options.full ?? false; + const cdpConnected = await this.#tryEnsureCdp(); + if ((0, _thread_ids_js__rspack_import_4.vr)(options.threadId)) { + if (!cdpConnected) { + throw new _errors_js__rspack_import_2.sO(`ChatGPT Desktop temporary thread ${options.threadId} requires CDP`); + } + return this.#cdp.readThread({ + ...options, + limit, + full + }); + } + if (cdpConnected && !full) { + const visible = await this.#cdp.readThread({ + ...options, + limit, + full: false + }); + if (limit <= visible.turns.length) { + return visible; + } + } try { - await this.#ensureCdp(); - return await this.#cdp.waitForReply(options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.waitForReply({ - threadId: options.threadId ?? 'unknown', - timeoutMs: options.timeoutMs + return await this.#fallbacks.readThread({ + threadId: options.threadId, + limit, + full }); + } catch (appError) { + if (cdpConnected) { + return this.#cdp.readThread({ + ...options, + limit, + full: true + }); + } + throw appError; } } + async sendMessage(options) { + await this.#ensureCdp(); + return this.#cdp.sendMessage(options); + } + async waitForReply(options) { + await this.#ensureCdp(); + return this.#cdp.waitForReply(options); + } async openThread(threadId, options) { try { await this.#ensureCdp(); @@ -9204,7 +9274,7 @@ var __webpack_modules__ = { port: this.#port, appServerFallback, reachable, - message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server fallback is available' : cdpStatus.message, + message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/deep-read' : cdpStatus.message, exitCode: reachable ? 0 : 1 }; } @@ -9219,6 +9289,47 @@ var __webpack_modules__ = { }); this.#cdpConnected = true; } + async #tryEnsureCdp() { + try { + await this.#ensureCdp(); + return true; + } catch (error) { + if (!isCdpFailure(error)) throw error; + this.#cdpConnected = false; + return false; + } + } + } + function mergeThreadLists(appList, cdpList) { + const cdpByKey = new Map(); + for (const thread of cdpList.threads){ + const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + cdpByKey.set(key, thread); + } + const merged = appList.threads.map((thread)=>{ + const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + const cdp = cdpByKey.get(key); + if (!cdp) return thread; + return { + ...thread, + title: thread.title || cdp.title, + pinned: cdp.pinned, + selected: cdp.selected, + kind: cdp.kind || thread.kind, + ...cdp.project !== undefined ? { + project: cdp.project + } : {} + }; + }); + for (const thread of cdpList.threads){ + if (merged.some((row)=>(0, _thread_ids_js__rspack_import_4.LV)(row.threadId, thread.threadId))) continue; + merged.push(thread); + } + return { + backend: 'app-server', + limit: appList.limit, + threads: merged.slice(0, appList.limit) + }; } function isCdpFailure(error) { if (error instanceof _errors_js__rspack_import_2.sO) return true; @@ -9481,6 +9592,50 @@ var __webpack_modules__ = { so: readThreadSchema }); }, + "./src/core/chatgpt-desktop/thread-ids.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _cdp_dom_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); + const LOCAL_THREAD_ID_PREFIX = 'local:'; + function isTemporaryDesktopThreadId(threadId) { + return threadId.startsWith(_cdp_dom_js__rspack_import_0.hA); + } + function toAppServerThreadId(threadId) { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return null; + if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) { + const bare = threadId.slice(LOCAL_THREAD_ID_PREFIX.length); + return bare || null; + } + return threadId; + } + function toDesktopThreadId(threadId) { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return threadId; + if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) return threadId; + return `${LOCAL_THREAD_ID_PREFIX}${threadId}`; + } + function threadIdsEquivalent(a, b) { + const left = toAppServerThreadId(a) ?? a; + const right = toAppServerThreadId(b) ?? b; + return left === right; + } + function appServerThreadIdCandidates(threadId) { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return []; + const bare = toAppServerThreadId(threadId); + const out = []; + const push = (id)=>{ + if (id && !out.includes(id)) out.push(id); + }; + push(bare); + push(threadId); + if (bare) push(toDesktopThreadId(bare)); + return out; + } + __webpack_require__.d(__webpack_exports__, { + BS: ()=>toDesktopThreadId, + EJ: ()=>appServerThreadIdCandidates, + LV: ()=>threadIdsEquivalent, + nn: ()=>toAppServerThreadId, + vr: ()=>isTemporaryDesktopThreadId + }); + }, "./src/core/claude-routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_1 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _claude_channel_js__rspack_import_0 = __webpack_require__("./src/core/claude-channel.js"); @@ -10051,7 +10206,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend "cdp" or "app-server".', + description: 'List ChatGPT Desktop threads via the Codex app-server when available (thread/list), merging CDP-only sidebar fields (pinned, selected, project, kind) when CDP is connected. Desktop local: maps to bare app-server ids. Result includes backend.', annotations: { readOnlyHint: true }, @@ -10094,7 +10249,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Open a ChatGPT Desktop sidebar thread (waits for Loading task… up to openTimeoutMs, default 90s) and harvest turns via local CDP. Default is visible turns only; full=true mouse-wheels the column-reverse timeline for history (skips history-gap placeholders). Falls back to Codex app-server when CDP is unreachable; result includes backend.', + description: 'Read a ChatGPT Desktop thread. Visible/recent turns use local CDP DOM harvest. full=true or a limit above the on-screen turns uses the Codex app-server (thread/read / resume); Desktop local: maps to the bare app-server id. DOM wheel crawl is only a fallback when app-server misses the thread. Result includes backend.', annotations: { readOnlyHint: true }, @@ -10111,14 +10266,15 @@ var __webpack_modules__ = { type: 'number' }, threadId: { - type: 'string' + type: 'string', + description: 'Desktop sidebar id (local:) or bare app-server thread id.' }, limit: { type: 'number' }, full: { type: 'boolean', - description: 'When true, wheel-crawl older history (slow). Default false = visible turns only.' + description: 'When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.' }, openTimeoutMs: { type: 'number', @@ -10152,7 +10308,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop send', - description: 'Send a message in ChatGPT Desktop via local CDP: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Falls back to app-server send when CDP is down and threadId is set.', + description: 'Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.', annotations: { readOnlyHint: false }, @@ -10210,7 +10366,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop status', - description: 'Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.', + description: 'Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.', annotations: { readOnlyHint: true }, @@ -10250,7 +10406,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop wait for reply', - description: 'Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). Falls back to app-server polling when CDP is unreachable.', + description: 'Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.', annotations: { readOnlyHint: true }, @@ -25964,7 +26120,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend \"cdp\" or \"app-server\".", + "description": "List ChatGPT Desktop threads via the Codex app-server when available (thread/list), merging CDP-only sidebar fields (pinned, selected, project, kind) when CDP is connected. Desktop local: maps to bare app-server ids. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -25992,12 +26148,12 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Open a ChatGPT Desktop sidebar thread (waits for Loading task… up to openTimeoutMs, default 90s) and harvest turns via local CDP. Default is visible turns only; full=true mouse-wheels the column-reverse timeline for history (skips history-gap placeholders). Falls back to Codex app-server when CDP is unreachable; result includes backend.", + "description": "Read a ChatGPT Desktop thread. Visible/recent turns use local CDP DOM harvest. full=true or a limit above the on-screen turns uses the Codex app-server (thread/read / resume); Desktop local: maps to the bare app-server id. DOM wheel crawl is only a fallback when app-server misses the thread. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { "full": { - "description": "When true, wheel-crawl older history (slow). Default false = visible turns only.", + "description": "When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.", "type": "boolean" }, "limit": { @@ -26011,6 +26167,7 @@ const routes = Object.freeze({ "type": "number" }, "threadId": { + "description": "Desktop sidebar id (local:) or bare app-server thread id.", "type": "string" } }, @@ -26035,7 +26192,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": false }, - "description": "Send a message in ChatGPT Desktop via local CDP: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Falls back to app-server send when CDP is down and threadId is set.", + "description": "Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -26078,7 +26235,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.", + "description": "Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -26103,7 +26260,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). Falls back to app-server polling when CDP is unreachable.", + "description": "Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.", "inputJsonSchema": { "additionalProperties": false, "properties": { diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index d676b00..4c6f19e 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -6494,6 +6494,7 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/app-server-fallback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); + var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); async function appServerListThreads({ limit = 50 } = {}) { const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit @@ -6501,117 +6502,71 @@ var __webpack_modules__ = { return { backend: 'app-server', limit: out.limit, - threads: out.threads.map((thread)=>({ - threadId: String(thread.id ?? ''), + threads: out.threads.map((thread)=>{ + const bare = String(thread.id ?? ''); + return { + threadId: bare ? (0, _thread_ids_js__rspack_import_1.BS)(bare) : '', title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), pinned: false, selected: false, kind: 'codex' - })) + }; + }) }; } async function appServerReadThread({ threadId, limit = 100, full = false }) { + const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); + if (candidates.length === 0) { + throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); + } const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { - let turns = []; - try { - const read = await client.request('thread/read', { - threadId - }); - const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - turns = normalizeTurns(raw).slice(full ? 0 : -limit); - if (full && limit > 0) turns = turns.slice(0, limit); - else if (!full) turns = turns.slice(-limit); - } catch { - const items = await client.request('thread/items/list', { - threadId, - limit: Math.min(limit, 100) - }); - turns = normalizeTurns(items.data ?? []).slice(-limit); + let lastError; + for (const candidate of candidates){ + try { + const turns = await readTurnsForId(client, candidate, { + limit, + full + }); + return { + threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), + turns, + backend: 'app-server', + limit, + full + }; + } catch (error) { + lastError = error; + } } - return { - threadId, - turns, - backend: 'app-server', - limit, - full - }; + throw lastError instanceof Error ? lastError : new Error(`app-server thread read failed for ${threadId}`); } finally{ client.close(); } } - async function appServerSendMessage({ threadId, text }) { - if (!threadId) { - return { - threadId: 'new', - backend: 'app-server', - experimental: false, - delivery: 'rejected', - message: 'app-server fallback requires an existing threadId; starting a new Desktop thread needs CDP' - }; - } - const receipt = await (0, _codex_bridge_js__rspack_import_0.ZS)(threadId, text); - return { - threadId, - backend: 'app-server', - experimental: false, - delivery: receipt.delivery ?? 'accepted', - message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined - }; - } - async function appServerWaitForReply({ threadId = 'unknown', timeoutMs = 60000 }) { - if (!threadId || threadId === 'unknown' || threadId === 'new') { - return { - threadId: threadId || 'unknown', - reply: '', - backend: 'app-server', - experimental: false, - delivery: 'rejected' - }; - } - const baseline = await appServerReadThread({ - threadId, - limit: 200 - }); - const seen = new Set(baseline.turns.map((turn)=>turn.turnKey)); - const deadline = Date.now() + timeoutMs; - while(Date.now() < deadline){ - await new Promise((resolve)=>setTimeout(resolve, 400)); - const page = await appServerReadThread({ - threadId, - limit: 200 - }); - const fresh = page.turns.filter((turn)=>!seen.has(turn.turnKey) && turn.role === 'assistant' && turn.text); - const reply = fresh.at(-1)?.text ?? ''; - if (reply) { - return { - threadId, - reply, - backend: 'app-server', - experimental: false, - delivery: 'replied' - }; - } - } - return { - threadId, - reply: '', - backend: 'app-server', - experimental: false, - delivery: 'timeout' - }; - } async function appServerOpenThread(threadId) { + const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); + if (candidates.length === 0) { + throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); + } const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { - await client.request('thread/resume', { - threadId, - excludeTurns: true - }); - return { - threadId, - backend: 'app-server' - }; + let lastError; + for (const candidate of candidates){ + try { + await client.request('thread/resume', { + threadId: candidate, + excludeTurns: true + }); + return { + threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), + backend: 'app-server' + }; + } catch (error) { + lastError = error; + } + } + throw lastError instanceof Error ? lastError : new Error(`app-server thread/resume failed for ${threadId}`); } finally{ client.close(); } @@ -6624,6 +6579,68 @@ var __webpack_modules__ = { socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined }; } + async function readTurnsForId(client, threadId, { limit, full }) { + try { + const read = await client.request('thread/read', { + threadId + }); + const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; + if (Array.isArray(raw) && raw.length > 0) { + return sliceTurns(normalizeTurns(raw), { + limit, + full + }); + } + } catch {} + try { + const resumed = await client.request('thread/resume', { + threadId, + excludeTurns: false + }); + const raw = resumed.thread?.turns ?? resumed.turns ?? resumed.thread?.items ?? []; + if (Array.isArray(raw) && raw.length > 0) { + return sliceTurns(normalizeTurns(raw), { + limit, + full + }); + } + } catch {} + for (const method of [ + 'thread/turns/list', + 'thread/items/list' + ]){ + try { + const collected = []; + let cursor; + for(let page = 0; page < 20; page++){ + const result = await client.request(method, { + threadId, + limit: 100, + ...cursor ? { + cursor + } : {} + }); + if (!Array.isArray(result.data)) break; + collected.push(...result.data); + if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; + cursor = result.nextCursor; + if (!full && collected.length >= limit) break; + } + if (collected.length > 0) { + return sliceTurns(normalizeTurns(collected), { + limit, + full + }); + } + } catch {} + } + throw new Error(`app-server has no turn history for thread ${threadId}`); + } + function sliceTurns(turns, { limit, full }) { + if (limit <= 0) return turns; + if (full) return turns.slice(0, limit); + return turns.slice(-limit); + } function normalizeTurns(raw) { const turns = []; for (const [index, item] of raw.entries()){ @@ -6643,10 +6660,8 @@ var __webpack_modules__ = { return turns; } __webpack_require__.d(__webpack_exports__, { - Ab: ()=>appServerSendMessage, Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, - bk: ()=>appServerWaitForReply, dM: ()=>appServerStatusProbe, zu: ()=>appServerOpenThread }); @@ -6948,6 +6963,18 @@ var __webpack_modules__ = { return out; } const LIST_THREADS_EXPRESSION = `(() => { + const skipProjectLabels = new Set(['Recent', 'Pinned', 'Threads', 'Chats']); + const projectFor = (row) => { + let el = row.parentElement; + for (let i = 0; i < 8 && el; i += 1, el = el.parentElement) { + const attr = + el.getAttribute('data-app-action-sidebar-project') || + el.getAttribute('data-app-action-sidebar-project-name') || + el.getAttribute('data-app-action-sidebar-section-title'); + if (attr && !skipProjectLabels.has(attr)) return attr; + } + return undefined; + }; const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); const seen = new Set(); const out = []; @@ -6955,12 +6982,14 @@ var __webpack_modules__ = { const threadId = row.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''; if (!threadId || seen.has(threadId)) continue; seen.add(threadId); + const project = projectFor(row); out.push({ threadId, title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + ...(project ? { project } : {}), }); } return out; @@ -7098,7 +7127,10 @@ var __webpack_modules__ = { title: String(row.title ?? ''), pinned: Boolean(row.pinned), selected: Boolean(row.selected), - kind: String(row.kind ?? 'unknown') + kind: String(row.kind ?? 'unknown'), + ...row.project ? { + project: String(row.project) + } : {} })); } async function openThreadInDom(session, sessionId, threadId) { @@ -7514,11 +7546,10 @@ var __webpack_modules__ = { var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, readThread: _app_server_fallback_js__rspack_import_1.Jf, - sendMessage: _app_server_fallback_js__rspack_import_1.Ab, - waitForReply: _app_server_fallback_js__rspack_import_1.bk, openThread: _app_server_fallback_js__rspack_import_1.zu, statusProbe: _app_server_fallback_js__rspack_import_1.dM }; @@ -7549,44 +7580,83 @@ var __webpack_modules__ = { return this.#cdp.listTargets(); } async listThreads(options) { + let appList = null; + let appError; try { - await this.#ensureCdp(); - return await this.#cdp.listThreads(options); + appList = await this.#fallbacks.listThreads(options); } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.listThreads(options); + appError = error; } - } - async readThread(options) { + let cdpList = null; + let cdpError; try { await this.#ensureCdp(); - return await this.#cdp.readThread(options); + cdpList = await this.#cdp.listThreads(options); } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.readThread(options); + if (isCdpFailure(error)) { + this.#cdpConnected = false; + } else { + cdpError = error; + } } - } - async sendMessage(options) { - try { - await this.#ensureCdp(); - return await this.#cdp.sendMessage(options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.sendMessage(options); + if (appList && cdpList) { + return mergeThreadLists(appList, cdpList); } + if (appList) return appList; + if (cdpList) return cdpList; + if (cdpError) throw cdpError; + if (appError) throw appError; + throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); } - async waitForReply(options) { + async readThread(options) { + const limit = options.limit ?? 100; + const full = options.full ?? false; + const cdpConnected = await this.#tryEnsureCdp(); + if ((0, _thread_ids_js__rspack_import_4.vr)(options.threadId)) { + if (!cdpConnected) { + throw new _errors_js__rspack_import_2.sO(`ChatGPT Desktop temporary thread ${options.threadId} requires CDP`); + } + return this.#cdp.readThread({ + ...options, + limit, + full + }); + } + if (cdpConnected && !full) { + const visible = await this.#cdp.readThread({ + ...options, + limit, + full: false + }); + if (limit <= visible.turns.length) { + return visible; + } + } try { - await this.#ensureCdp(); - return await this.#cdp.waitForReply(options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.waitForReply({ - threadId: options.threadId ?? 'unknown', - timeoutMs: options.timeoutMs + return await this.#fallbacks.readThread({ + threadId: options.threadId, + limit, + full }); + } catch (appError) { + if (cdpConnected) { + return this.#cdp.readThread({ + ...options, + limit, + full: true + }); + } + throw appError; } } + async sendMessage(options) { + await this.#ensureCdp(); + return this.#cdp.sendMessage(options); + } + async waitForReply(options) { + await this.#ensureCdp(); + return this.#cdp.waitForReply(options); + } async openThread(threadId, options) { try { await this.#ensureCdp(); @@ -7612,7 +7682,7 @@ var __webpack_modules__ = { port: this.#port, appServerFallback, reachable, - message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server fallback is available' : cdpStatus.message, + message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/deep-read' : cdpStatus.message, exitCode: reachable ? 0 : 1 }; } @@ -7627,6 +7697,47 @@ var __webpack_modules__ = { }); this.#cdpConnected = true; } + async #tryEnsureCdp() { + try { + await this.#ensureCdp(); + return true; + } catch (error) { + if (!isCdpFailure(error)) throw error; + this.#cdpConnected = false; + return false; + } + } + } + function mergeThreadLists(appList, cdpList) { + const cdpByKey = new Map(); + for (const thread of cdpList.threads){ + const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + cdpByKey.set(key, thread); + } + const merged = appList.threads.map((thread)=>{ + const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + const cdp = cdpByKey.get(key); + if (!cdp) return thread; + return { + ...thread, + title: thread.title || cdp.title, + pinned: cdp.pinned, + selected: cdp.selected, + kind: cdp.kind || thread.kind, + ...cdp.project !== undefined ? { + project: cdp.project + } : {} + }; + }); + for (const thread of cdpList.threads){ + if (merged.some((row)=>(0, _thread_ids_js__rspack_import_4.LV)(row.threadId, thread.threadId))) continue; + merged.push(thread); + } + return { + backend: 'app-server', + limit: appList.limit, + threads: merged.slice(0, appList.limit) + }; } function isCdpFailure(error) { if (error instanceof _errors_js__rspack_import_2.sO) return true; @@ -7889,6 +8000,50 @@ var __webpack_modules__ = { so: readThreadSchema }); }, + "./src/core/chatgpt-desktop/thread-ids.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _cdp_dom_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); + const LOCAL_THREAD_ID_PREFIX = 'local:'; + function isTemporaryDesktopThreadId(threadId) { + return threadId.startsWith(_cdp_dom_js__rspack_import_0.hA); + } + function toAppServerThreadId(threadId) { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return null; + if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) { + const bare = threadId.slice(LOCAL_THREAD_ID_PREFIX.length); + return bare || null; + } + return threadId; + } + function toDesktopThreadId(threadId) { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return threadId; + if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) return threadId; + return `${LOCAL_THREAD_ID_PREFIX}${threadId}`; + } + function threadIdsEquivalent(a, b) { + const left = toAppServerThreadId(a) ?? a; + const right = toAppServerThreadId(b) ?? b; + return left === right; + } + function appServerThreadIdCandidates(threadId) { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return []; + const bare = toAppServerThreadId(threadId); + const out = []; + const push = (id)=>{ + if (id && !out.includes(id)) out.push(id); + }; + push(bare); + push(threadId); + if (bare) push(toDesktopThreadId(bare)); + return out; + } + __webpack_require__.d(__webpack_exports__, { + BS: ()=>toDesktopThreadId, + EJ: ()=>appServerThreadIdCandidates, + LV: ()=>threadIdsEquivalent, + nn: ()=>toAppServerThreadId, + vr: ()=>isTemporaryDesktopThreadId + }); + }, "./src/core/claude-routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_1 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _claude_channel_js__rspack_import_0 = __webpack_require__("./src/core/claude-channel.js"); @@ -8459,7 +8614,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend "cdp" or "app-server".', + description: 'List ChatGPT Desktop threads via the Codex app-server when available (thread/list), merging CDP-only sidebar fields (pinned, selected, project, kind) when CDP is connected. Desktop local: maps to bare app-server ids. Result includes backend.', annotations: { readOnlyHint: true }, @@ -8502,7 +8657,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Open a ChatGPT Desktop sidebar thread (waits for Loading task… up to openTimeoutMs, default 90s) and harvest turns via local CDP. Default is visible turns only; full=true mouse-wheels the column-reverse timeline for history (skips history-gap placeholders). Falls back to Codex app-server when CDP is unreachable; result includes backend.', + description: 'Read a ChatGPT Desktop thread. Visible/recent turns use local CDP DOM harvest. full=true or a limit above the on-screen turns uses the Codex app-server (thread/read / resume); Desktop local: maps to the bare app-server id. DOM wheel crawl is only a fallback when app-server misses the thread. Result includes backend.', annotations: { readOnlyHint: true }, @@ -8519,14 +8674,15 @@ var __webpack_modules__ = { type: 'number' }, threadId: { - type: 'string' + type: 'string', + description: 'Desktop sidebar id (local:) or bare app-server thread id.' }, limit: { type: 'number' }, full: { type: 'boolean', - description: 'When true, wheel-crawl older history (slow). Default false = visible turns only.' + description: 'When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.' }, openTimeoutMs: { type: 'number', @@ -8560,7 +8716,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop send', - description: 'Send a message in ChatGPT Desktop via local CDP: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Falls back to app-server send when CDP is down and threadId is set.', + description: 'Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.', annotations: { readOnlyHint: false }, @@ -8618,7 +8774,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop status', - description: 'Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.', + description: 'Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.', annotations: { readOnlyHint: true }, @@ -8658,7 +8814,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop wait for reply', - description: 'Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). Falls back to app-server polling when CDP is unreachable.', + description: 'Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.', annotations: { readOnlyHint: true }, @@ -57842,7 +57998,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend \"cdp\" or \"app-server\".", + "description": "List ChatGPT Desktop threads via the Codex app-server when available (thread/list), merging CDP-only sidebar fields (pinned, selected, project, kind) when CDP is connected. Desktop local: maps to bare app-server ids. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -57869,12 +58025,12 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Open a ChatGPT Desktop sidebar thread (waits for Loading task… up to openTimeoutMs, default 90s) and harvest turns via local CDP. Default is visible turns only; full=true mouse-wheels the column-reverse timeline for history (skips history-gap placeholders). Falls back to Codex app-server when CDP is unreachable; result includes backend.", + "description": "Read a ChatGPT Desktop thread. Visible/recent turns use local CDP DOM harvest. full=true or a limit above the on-screen turns uses the Codex app-server (thread/read / resume); Desktop local: maps to the bare app-server id. DOM wheel crawl is only a fallback when app-server misses the thread. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { "full": { - "description": "When true, wheel-crawl older history (slow). Default false = visible turns only.", + "description": "When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.", "type": "boolean" }, "limit": { @@ -57888,6 +58044,7 @@ var __webpack_modules__ = { "type": "number" }, "threadId": { + "description": "Desktop sidebar id (local:) or bare app-server thread id.", "type": "string" } }, @@ -57911,7 +58068,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": false }, - "description": "Send a message in ChatGPT Desktop via local CDP: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Falls back to app-server send when CDP is down and threadId is set.", + "description": "Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -57953,7 +58110,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.", + "description": "Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -57977,7 +58134,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). Falls back to app-server polling when CDP is unreachable.", + "description": "Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.", "inputJsonSchema": { "additionalProperties": false, "properties": { diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index bb32711..94a07c9 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -38,12 +38,46 @@ gbot chatgpt-desktop send "start a new chat with this text" | Tool | Role | | --- | --- | | `chatgpt_desktop_status` | CDP `/json/version` (+ optional attach) and app-server probe | -| `chatgpt_desktop_list_threads` | Sidebar threads via CDP; app-server `thread/list` fallback | -| `chatgpt_desktop_read_thread` | Virtualized timeline harvest; app-server read/items fallback | -| `chatgpt_desktop_send` | Experimental composer submit; app-server send fallback | -| `chatgpt_desktop_wait_reply` | Experimental poll for a new assistant turn | - -Every mutating/list/read result includes `backend: "cdp" | "app-server"`. +| `chatgpt_desktop_list_threads` | App-server `thread/list` when available; merges CDP sidebar fields | +| `chatgpt_desktop_read_thread` | Visible turns via CDP; deep/full history via app-server | +| `chatgpt_desktop_send` | Composer submit over CDP (new-thread-in-project included) | +| `chatgpt_desktop_wait_reply` | Poll for a new assistant turn over CDP | + +Every list/read/send/wait/open result includes `backend: "cdp" | "app-server"`. + +## Thread id mapping + +Desktop sidebar rows expose `data-app-action-sidebar-thread-id` as +`local:`. The Codex app-server uses the bare `` +for `thread/list`, `thread/read`, and `thread/resume`. + +| Form | Example | Where | +| --- | --- | --- | +| Desktop sidebar | `local:11111111-1111-1111-1111-111111111111` | CDP DOM | +| App-server | `11111111-1111-1111-1111-111111111111` | `codex-bridge` / app-server | +| Temporary (CDP-only) | `local:client-new-thread:…` | Composer before first reply | + +Helpers in `thread-ids.ts` (`toAppServerThreadId`, `toDesktopThreadId`, +`appServerThreadIdCandidates`) accept either durable form. Temporary +`local:client-new-thread:…` ids do **not** map until +`data-response-annotation-conversation` resolves a real conversation id. +List/read results prefer the Desktop `local:…` form so callers can round-trip +the same id into send/wait. + +## Backend capability matrix + +| Operation | CDP | App-server | +| --- | --- | --- | +| `status` | `/json/version` + attach | daemon probe (`codexStatus`) | +| `list_threads` | sidebar DOM (pinned/selected/project/kind) | primary inventory (`thread/list`) | +| `read_thread` (visible / limit ≤ on-screen) | harvest rendered turns | — | +| `read_thread` (full / limit > visible) | wheel crawl **fallback only** | primary (`thread/read`, resume+turns, turns/items list) | +| `open_thread` | click sidebar row | `thread/resume` fallback when CDP down | +| `send` / new-thread-in-project | composer + Enter / project button | **not used** | +| `wait_reply` | Stop gone + final-assistant | **not used** | + +List merges app-server rows with CDP-only fields (`pinned`, `selected`, +`project`, `kind`) when CDP is connected, and appends CDP-only temporary rows. ## Target selection @@ -63,13 +97,12 @@ All selectors live in `src/core/chatgpt-desktop/cdp-dom.ts`: - New chat: `button[aria-label="Start new chat in "]` (preferred) or sidebar “New chat” - Conversation id: `[data-response-annotation-conversation]` (resolves `local:client-new-thread:…`) - Open: click sidebar row, wait until “Loading task…” clears (default 90s) -- Full read: mouseWheel (negative deltaY) on `[data-app-action-timeline-scroll]` (column-reverse); skip `history-gap:` keys +- Visible read: harvest currently rendered turns (no wheel) +- Full-read fallback: mouseWheel (negative deltaY) on `[data-app-action-timeline-scroll]` (column-reverse); skip `history-gap:` keys — only when app-server misses the thread or is unreachable -## Fallback +## App-server reuse -CDP is the primary path for `chatgpt_desktop_*` because Desktop can do more -than the Codex app-server. When CDP is unreachable, list/read/send/wait/open -reuse the existing client in `codex-bridge.js` (`listCodexThreads`, -`openCodexSession`, `sendToCodexThread`, `codexStatus`) — no duplicated -JSON-RPC stack. Each of those results includes `backend: "cdp" | "app-server"`. -Starting a brand-new Desktop thread without a `threadId` still needs CDP. +Deep history and thread listing reuse the existing client in `codex-bridge.js` +(`listCodexThreads`, `openCodexSession`, `codexStatus`) — no duplicated +JSON-RPC stack. Send / new-thread-in-project / wait-for-reply stay on CDP +because those Desktop UI actions are not app-server operations in this adapter. diff --git a/src/cli/chatgpt-desktop/read.tsx b/src/cli/chatgpt-desktop/read.tsx index 0d122cb..a71b738 100644 --- a/src/cli/chatgpt-desktop/read.tsx +++ b/src/cli/chatgpt-desktop/read.tsx @@ -10,7 +10,7 @@ import { export const config = { description: - 'Read a ChatGPT Desktop thread via CDP. Default: visible turns. --full wheel-crawls history.', + 'Read a ChatGPT Desktop thread. Visible turns via CDP; --full / deep history via app-server (wheel crawl last-resort).', exitCode: 'result', positionals: ['threadId'], inputJsonSchema: { diff --git a/src/cli/chatgpt-desktop/status.tsx b/src/cli/chatgpt-desktop/status.tsx index 2d098e2..1eb5954 100644 --- a/src/cli/chatgpt-desktop/status.tsx +++ b/src/cli/chatgpt-desktop/status.tsx @@ -10,7 +10,7 @@ import { export const config = { description: - 'Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server fallback availability.', + 'Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, diff --git a/src/cli/chatgpt-desktop/threads.tsx b/src/cli/chatgpt-desktop/threads.tsx index 5db6da5..abec1f0 100644 --- a/src/cli/chatgpt-desktop/threads.tsx +++ b/src/cli/chatgpt-desktop/threads.tsx @@ -9,7 +9,8 @@ import { } from '../../core/chatgpt-desktop/routes.js'; export const config = { - description: 'List ChatGPT Desktop threads via CDP (app-server fallback when CDP is down).', + description: + 'List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, diff --git a/src/core/chatgpt-desktop/app-server-fallback.ts b/src/core/chatgpt-desktop/app-server-fallback.ts index 2b4d153..c1e9dde 100644 --- a/src/core/chatgpt-desktop/app-server-fallback.ts +++ b/src/core/chatgpt-desktop/app-server-fallback.ts @@ -1,21 +1,23 @@ /** - * App-server fallback for ChatGPT Desktop operations that also exist on the - * managed Codex daemon. Reuses the existing codex-bridge client — does not - * duplicate the WebSocket/JSON-RPC stack. + * App-server path for ChatGPT Desktop list/deep-read/open. + * Reuses the existing codex-bridge client — does not duplicate the WebSocket/JSON-RPC stack. + * + * Send, new-thread-in-project, and wait-for-reply stay on CDP (see facade). */ import { codexStatus, listCodexThreads, openCodexSession, - sendToCodexThread, } from '../codex-bridge.js'; +import { + appServerThreadIdCandidates, + toDesktopThreadId, +} from './thread-ids.js'; import type { ListThreadsResult, OpenThreadResult, ReadThreadResult, - SendMessageResult, - WaitForReplyResult, } from './types.js'; export async function appServerListThreads({ @@ -32,13 +34,17 @@ export async function appServerListThreads({ name?: string; preview?: string; cwd?: string; - }) => ({ - threadId: String(thread.id ?? ''), - title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), - pinned: false, - selected: false, - kind: 'codex', - })), + }) => { + const bare = String(thread.id ?? ''); + return { + // Present Desktop-form ids so callers can pass them straight back to read/send. + threadId: bare ? toDesktopThreadId(bare) : '', + title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), + pinned: false, + selected: false, + kind: 'codex', + }; + }), }; } @@ -51,108 +57,59 @@ export async function appServerReadThread({ limit?: number; full?: boolean; }): Promise { + const candidates = appServerThreadIdCandidates(threadId); + if (candidates.length === 0) { + throw new Error( + `No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`, + ); + } + const { client } = await openCodexSession(); try { - let turns: ReadThreadResult['turns'] = []; - try { - const read = await client.request('thread/read', { threadId }) as { - thread?: { turns?: unknown[]; items?: unknown[] }; - turns?: unknown[]; - items?: unknown[]; - }; - const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - turns = normalizeTurns(raw).slice(full ? 0 : -limit); - if (full && limit > 0) turns = turns.slice(0, limit); - else if (!full) turns = turns.slice(-limit); - } catch { - const items = await client.request('thread/items/list', { - threadId, - limit: Math.min(limit, 100), - }) as { data?: unknown[] }; - turns = normalizeTurns(items.data ?? []).slice(-limit); + let lastError: unknown; + for (const candidate of candidates) { + try { + const turns = await readTurnsForId(client, candidate, { limit, full }); + return { + threadId: toDesktopThreadId(candidate), + turns, + backend: 'app-server', + limit, + full, + }; + } catch (error) { + lastError = error; + } } - return { threadId, turns, backend: 'app-server', limit, full }; + throw lastError instanceof Error + ? lastError + : new Error(`app-server thread read failed for ${threadId}`); } finally { client.close(); } } -export async function appServerSendMessage({ - threadId, - text, -}: { - threadId?: string; - text: string; -}): Promise { - if (!threadId) { - return { - threadId: 'new', - backend: 'app-server', - experimental: false, - delivery: 'rejected', - message: - 'app-server fallback requires an existing threadId; starting a new Desktop thread needs CDP', - }; - } - const receipt = await sendToCodexThread(threadId, text); - return { - threadId, - backend: 'app-server', - experimental: false, - delivery: (receipt.delivery as SendMessageResult['delivery']) ?? 'accepted', - message: typeof receipt.turnId === 'string' ? `turn ${receipt.turnId}` : undefined, - }; -} - -export async function appServerWaitForReply({ - threadId = 'unknown', - timeoutMs = 60000, -}: { - threadId?: string; - timeoutMs?: number; -}): Promise { - if (!threadId || threadId === 'unknown' || threadId === 'new') { - return { - threadId: threadId || 'unknown', - reply: '', - backend: 'app-server', - experimental: false, - delivery: 'rejected', - }; - } - // Reuse the existing session client; poll thread/items/list for a fresh agent message. - const baseline = await appServerReadThread({ threadId, limit: 200 }); - const seen = new Set(baseline.turns.map((turn) => turn.turnKey)); - const deadline = Date.now() + timeoutMs; - while (Date.now() < deadline) { - await new Promise((resolve) => setTimeout(resolve, 400)); - const page = await appServerReadThread({ threadId, limit: 200 }); - const fresh = page.turns.filter((turn) => !seen.has(turn.turnKey) && turn.role === 'assistant' && turn.text); - const reply = fresh.at(-1)?.text ?? ''; - if (reply) { - return { - threadId, - reply, - backend: 'app-server', - experimental: false, - delivery: 'replied', - }; - } - } - return { - threadId, - reply: '', - backend: 'app-server', - experimental: false, - delivery: 'timeout', - }; -} - export async function appServerOpenThread(threadId: string): Promise { + const candidates = appServerThreadIdCandidates(threadId); + if (candidates.length === 0) { + throw new Error( + `No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`, + ); + } const { client } = await openCodexSession(); try { - await client.request('thread/resume', { threadId, excludeTurns: true }); - return { threadId, backend: 'app-server' }; + let lastError: unknown; + for (const candidate of candidates) { + try { + await client.request('thread/resume', { threadId: candidate, excludeTurns: true }); + return { threadId: toDesktopThreadId(candidate), backend: 'app-server' }; + } catch (error) { + lastError = error; + } + } + throw lastError instanceof Error + ? lastError + : new Error(`app-server thread/resume failed for ${threadId}`); } finally { client.close(); } @@ -175,6 +132,83 @@ export async function appServerStatusProbe(): Promise<{ }; } +type AppServerClient = { + request: (method: string, params?: Record) => Promise; +}; + +async function readTurnsForId( + client: AppServerClient, + threadId: string, + { limit, full }: { limit: number; full: boolean }, +): Promise { + // Prefer thread/read (full history inspection). Fall back to resume-with-turns, + // then paginated turns/items lists — same client, no duplicated transport. + try { + const read = await client.request('thread/read', { threadId }) as { + thread?: { turns?: unknown[]; items?: unknown[] }; + turns?: unknown[]; + items?: unknown[]; + }; + const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; + if (Array.isArray(raw) && raw.length > 0) { + return sliceTurns(normalizeTurns(raw), { limit, full }); + } + } catch { + // try resume / list below + } + + try { + const resumed = await client.request('thread/resume', { + threadId, + excludeTurns: false, + }) as { + thread?: { turns?: unknown[]; items?: unknown[] }; + turns?: unknown[]; + }; + const raw = resumed.thread?.turns ?? resumed.turns ?? resumed.thread?.items ?? []; + if (Array.isArray(raw) && raw.length > 0) { + return sliceTurns(normalizeTurns(raw), { limit, full }); + } + } catch { + // try list below + } + + for (const method of ['thread/turns/list', 'thread/items/list'] as const) { + try { + const collected: unknown[] = []; + let cursor: string | undefined; + for (let page = 0; page < 20; page++) { + const result = await client.request(method, { + threadId, + limit: 100, + ...(cursor ? { cursor } : {}), + }) as { data?: unknown[]; nextCursor?: string | null }; + if (!Array.isArray(result.data)) break; + collected.push(...result.data); + if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; + cursor = result.nextCursor; + if (!full && collected.length >= limit) break; + } + if (collected.length > 0) { + return sliceTurns(normalizeTurns(collected), { limit, full }); + } + } catch { + // try next method + } + } + + throw new Error(`app-server has no turn history for thread ${threadId}`); +} + +function sliceTurns( + turns: ReadThreadResult['turns'], + { limit, full }: { limit: number; full: boolean }, +): ReadThreadResult['turns'] { + if (limit <= 0) return turns; + if (full) return turns.slice(0, limit); + return turns.slice(-limit); +} + function normalizeTurns(raw: unknown[]): ReadThreadResult['turns'] { const turns: Array = []; for (const [index, item] of raw.entries()) { diff --git a/src/core/chatgpt-desktop/cdp-dom.ts b/src/core/chatgpt-desktop/cdp-dom.ts index 4735225..5781410 100644 --- a/src/core/chatgpt-desktop/cdp-dom.ts +++ b/src/core/chatgpt-desktop/cdp-dom.ts @@ -132,6 +132,18 @@ export function dedupeThreadsById( } export const LIST_THREADS_EXPRESSION = `(() => { + const skipProjectLabels = new Set(['Recent', 'Pinned', 'Threads', 'Chats']); + const projectFor = (row) => { + let el = row.parentElement; + for (let i = 0; i < 8 && el; i += 1, el = el.parentElement) { + const attr = + el.getAttribute('data-app-action-sidebar-project') || + el.getAttribute('data-app-action-sidebar-project-name') || + el.getAttribute('data-app-action-sidebar-section-title'); + if (attr && !skipProjectLabels.has(attr)) return attr; + } + return undefined; + }; const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); const seen = new Set(); const out = []; @@ -139,12 +151,14 @@ export const LIST_THREADS_EXPRESSION = `(() => { const threadId = row.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''; if (!threadId || seen.has(threadId)) continue; seen.add(threadId); + const project = projectFor(row); out.push({ threadId, title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', kind: row.getAttribute(${JSON.stringify(ATTR.threadKind)}) || 'unknown', + ...(project ? { project } : {}), }); } return out; @@ -297,6 +311,7 @@ export async function listThreadsFromDom( pinned: Boolean(row.pinned), selected: Boolean(row.selected), kind: String(row.kind ?? 'unknown'), + ...(row.project ? { project: String(row.project) } : {}), })); } diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index 370ff53..0e952c3 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -4,15 +4,19 @@ import { appServerListThreads, appServerOpenThread, appServerReadThread, - appServerSendMessage, appServerStatusProbe, - appServerWaitForReply, } from './app-server-fallback.js'; import { CdpUnreachableError, NotImplementedError } from './errors.js'; import { resolveCdpPort } from './loopback.js'; +import { + isTemporaryDesktopThreadId, + threadIdsEquivalent, + toAppServerThreadId, +} from './thread-ids.js'; import type { ChatGptDesktopStatus, ChatGptDesktopTarget, + ChatGptDesktopThread, ListThreadsResult, OpenThreadResult, ReadThreadResult, @@ -20,12 +24,10 @@ import type { WaitForReplyResult, } from './types.js'; -/** Optional overrides so tests can prove CDP→app-server fallback without a live daemon. */ +/** Optional overrides so tests can prove app-server / CDP routing without a live daemon. */ export type ChatGptDesktopFallbacks = { listThreads: typeof appServerListThreads; readThread: typeof appServerReadThread; - sendMessage: typeof appServerSendMessage; - waitForReply: typeof appServerWaitForReply; openThread: typeof appServerOpenThread; statusProbe: typeof appServerStatusProbe; }; @@ -33,17 +35,20 @@ export type ChatGptDesktopFallbacks = { const defaultFallbacks: ChatGptDesktopFallbacks = { listThreads: appServerListThreads, readThread: appServerReadThread, - sendMessage: appServerSendMessage, - waitForReply: appServerWaitForReply, openThread: appServerOpenThread, statusProbe: appServerStatusProbe, }; /** - * Prefer CDP for ChatGPT Desktop (Desktop can do more than app-server). - * When CDP is unreachable, reuse the existing Codex app-server client for - * operations it already serves — never duplicate that JSON-RPC stack. - * Every list/read/send/wait/open result reports `backend: "cdp" | "app-server"`. + * ChatGPT Desktop facade. + * + * - List: app-server when available; merge CDP-only fields (pinned/selected/project). + * - Read: visible/recent stays on CDP DOM; deep / full-history uses app-server + * (`thread/read` / resume with turns). DOM wheel crawl is last-resort only. + * - Send, new-thread-in-project, wait-for-reply: CDP only. + * - Every list/read/send/wait/open result reports `backend: "cdp" | "app-server"`. + * + * Reuses the existing Codex app-server client — never duplicates that JSON-RPC stack. */ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { #cdp: ChatGptDesktopAdapter; @@ -78,13 +83,36 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { } async listThreads(options?: { limit?: number }): Promise { + let appList: ListThreadsResult | null = null; + let appError: unknown; + try { + appList = await this.#fallbacks.listThreads(options); + } catch (error) { + appError = error; + } + + let cdpList: ListThreadsResult | null = null; + let cdpError: unknown; try { await this.#ensureCdp(); - return await this.#cdp.listThreads(options); + cdpList = await this.#cdp.listThreads(options); } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.listThreads(options); + if (isCdpFailure(error)) { + this.#cdpConnected = false; + } else { + cdpError = error; + } } + + if (appList && cdpList) { + return mergeThreadLists(appList, cdpList); + } + // App-server is primary; CDP merge is best-effort (skip NotImplemented / other DOM gaps). + if (appList) return appList; + if (cdpList) return cdpList; + if (cdpError) throw cdpError; + if (appError) throw appError; + throw new CdpUnreachableError('ChatGPT Desktop listThreads: CDP and app-server unreachable'); } async readThread(options: { @@ -93,12 +121,44 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { full?: boolean; openTimeoutMs?: number; }): Promise { + const limit = options.limit ?? 100; + const full = options.full ?? false; + const cdpConnected = await this.#tryEnsureCdp(); + + // Temporary sidebar rows have no app-server mapping — CDP only. + if (isTemporaryDesktopThreadId(options.threadId)) { + if (!cdpConnected) { + throw new CdpUnreachableError( + `ChatGPT Desktop temporary thread ${options.threadId} requires CDP`, + ); + } + return this.#cdp.readThread({ ...options, limit, full }); + } + + // Quick visible/recent read via CDP when that is enough. + if (cdpConnected && !full) { + const visible = await this.#cdp.readThread({ ...options, limit, full: false }); + if (limit <= visible.turns.length) { + return visible; + } + // Requested more turns than the DOM shows — escalate to app-server. + } + + // Deep / full-history: app-server first. try { - await this.#ensureCdp(); - return await this.#cdp.readThread(options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.readThread(options); + return await this.#fallbacks.readThread({ + threadId: options.threadId, + limit, + // Preserve caller intent: full=true takes history from the start; + // otherwise return the most recent `limit` turns from full history. + full, + }); + } catch (appError) { + // DOM wheel crawl only when app-server does not know the thread / is unreachable. + if (cdpConnected) { + return this.#cdp.readThread({ ...options, limit, full: true }); + } + throw appError; } } @@ -108,29 +168,16 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { project?: string; openTimeoutMs?: number; }): Promise { - try { - await this.#ensureCdp(); - return await this.#cdp.sendMessage(options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.sendMessage(options); - } + await this.#ensureCdp(); + return this.#cdp.sendMessage(options); } async waitForReply(options: { threadId?: string; timeoutMs?: number; }): Promise { - try { - await this.#ensureCdp(); - return await this.#cdp.waitForReply(options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.waitForReply({ - threadId: options.threadId ?? 'unknown', - timeoutMs: options.timeoutMs, - }); - } + await this.#ensureCdp(); + return this.#cdp.waitForReply(options); } async openThread( @@ -163,7 +210,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable - ? 'CDP unreachable; Codex app-server fallback is available' + ? 'CDP unreachable; Codex app-server available for list/deep-read' : cdpStatus.message, exitCode: reachable ? 0 : 1, }; @@ -179,6 +226,55 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { await this.#cdp.connect({ port: this.#port }); this.#cdpConnected = true; } + + async #tryEnsureCdp(): Promise { + try { + await this.#ensureCdp(); + return true; + } catch (error) { + if (!isCdpFailure(error)) throw error; + this.#cdpConnected = false; + return false; + } + } +} + +/** Merge app-server thread inventory with CDP-only sidebar fields. */ +export function mergeThreadLists( + appList: ListThreadsResult, + cdpList: ListThreadsResult, +): ListThreadsResult { + const cdpByKey = new Map(); + for (const thread of cdpList.threads) { + const key = toAppServerThreadId(thread.threadId) ?? thread.threadId; + cdpByKey.set(key, thread); + } + + const merged: ChatGptDesktopThread[] = appList.threads.map((thread) => { + const key = toAppServerThreadId(thread.threadId) ?? thread.threadId; + const cdp = cdpByKey.get(key); + if (!cdp) return thread; + return { + ...thread, + title: thread.title || cdp.title, + pinned: cdp.pinned, + selected: cdp.selected, + kind: cdp.kind || thread.kind, + ...(cdp.project !== undefined ? { project: cdp.project } : {}), + }; + }); + + // Keep CDP-only rows (e.g. temporary local:client-new-thread:…) visible. + for (const thread of cdpList.threads) { + if (merged.some((row) => threadIdsEquivalent(row.threadId, thread.threadId))) continue; + merged.push(thread); + } + + return { + backend: 'app-server', + limit: appList.limit, + threads: merged.slice(0, appList.limit), + }; } function isCdpFailure(error: unknown): boolean { diff --git a/src/core/chatgpt-desktop/index.ts b/src/core/chatgpt-desktop/index.ts index 7426fae..0e1efee 100644 --- a/src/core/chatgpt-desktop/index.ts +++ b/src/core/chatgpt-desktop/index.ts @@ -27,9 +27,18 @@ export { export { ChatGptDesktopFacade, getChatGptDesktopAdapter, + mergeThreadLists, setChatGptDesktopAdapterForTests, } from './facade.js'; export type { ChatGptDesktopFallbacks } from './facade.js'; +export { + LOCAL_THREAD_ID_PREFIX, + appServerThreadIdCandidates, + isTemporaryDesktopThreadId, + threadIdsEquivalent, + toAppServerThreadId, + toDesktopThreadId, +} from './thread-ids.js'; export { CDP_LOOPBACK_HOST, DEFAULT_CDP_PORT, diff --git a/src/core/chatgpt-desktop/routes.ts b/src/core/chatgpt-desktop/routes.ts index 86462cf..de641c6 100644 --- a/src/core/chatgpt-desktop/routes.ts +++ b/src/core/chatgpt-desktop/routes.ts @@ -65,7 +65,7 @@ async function withAdapter( try { await adapter.connect({ port: resolved }); } catch { - // status/list may still succeed via HTTP probe or app-server fallback. + // status/list may still succeed via HTTP probe or app-server list/deep-read. } return run(adapter); } diff --git a/src/core/chatgpt-desktop/thread-ids.ts b/src/core/chatgpt-desktop/thread-ids.ts new file mode 100644 index 0000000..9495886 --- /dev/null +++ b/src/core/chatgpt-desktop/thread-ids.ts @@ -0,0 +1,63 @@ +/** + * Desktop sidebar thread ids ↔ Codex app-server thread ids. + * + * ChatGPT Desktop sidebar rows use `data-app-action-sidebar-thread-id` values + * shaped like `local:`. The Codex app-server `thread/list`, + * `thread/read`, and `thread/resume` APIs use the bare ``. + * + * Temporary composer rows (`local:client-new-thread:…`) are CDP-only until the + * first reply annotates a real conversation id — they do not map to app-server. + */ + +import { TEMP_THREAD_ID_PREFIX } from './cdp-dom.js'; + +export const LOCAL_THREAD_ID_PREFIX = 'local:' as const; + +/** True when the id is a transient sidebar row, not a durable conversation. */ +export function isTemporaryDesktopThreadId(threadId: string): boolean { + return threadId.startsWith(TEMP_THREAD_ID_PREFIX); +} + +/** + * Map a Desktop sidebar id to the app-server thread id. + * Returns null when the id is temporary or empty (no app-server mapping). + */ +export function toAppServerThreadId(threadId: string): string | null { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return null; + if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) { + const bare = threadId.slice(LOCAL_THREAD_ID_PREFIX.length); + return bare || null; + } + return threadId; +} + +/** Present an app-server (or bare) id in Desktop sidebar form. */ +export function toDesktopThreadId(threadId: string): string { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return threadId; + if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) return threadId; + return `${LOCAL_THREAD_ID_PREFIX}${threadId}`; +} + +/** Compare Desktop and app-server id forms as the same conversation. */ +export function threadIdsEquivalent(a: string, b: string): boolean { + const left = toAppServerThreadId(a) ?? a; + const right = toAppServerThreadId(b) ?? b; + return left === right; +} + +/** + * Ordered candidates to try against app-server. Prefer the bare conversation + * id; also try the original and `local:` form so mapping can be verified. + */ +export function appServerThreadIdCandidates(threadId: string): string[] { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return []; + const bare = toAppServerThreadId(threadId); + const out: string[] = []; + const push = (id: string | null | undefined) => { + if (id && !out.includes(id)) out.push(id); + }; + push(bare); + push(threadId); + if (bare) push(toDesktopThreadId(bare)); + return out; +} diff --git a/src/core/chatgpt-desktop/types.ts b/src/core/chatgpt-desktop/types.ts index ab09e1a..d07da12 100644 --- a/src/core/chatgpt-desktop/types.ts +++ b/src/core/chatgpt-desktop/types.ts @@ -14,6 +14,8 @@ export type ChatGptDesktopThread = { readonly pinned: boolean; readonly selected: boolean; readonly kind: string; + /** CDP-only: project folder from the sidebar when known. */ + readonly project?: string; }; export type ChatGptDesktopTurn = { diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx index ee995ca..f174ad4 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list threads', description: - 'List ChatGPT Desktop sidebar threads via local CDP (127.0.0.1 only). Falls back to the Codex app-server daemon when CDP is unreachable; the result includes backend "cdp" or "app-server".', + 'List ChatGPT Desktop threads via the Codex app-server when available (thread/list), merging CDP-only sidebar fields (pinned, selected, project, kind) when CDP is connected. Desktop local: maps to bare app-server ids. Result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx index 81471ea..b5f2925 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop read thread', description: - 'Open a ChatGPT Desktop sidebar thread (waits for Loading task… up to openTimeoutMs, default 90s) and harvest turns via local CDP. Default is visible turns only; full=true mouse-wheels the column-reverse timeline for history (skips history-gap placeholders). Falls back to Codex app-server when CDP is unreachable; result includes backend.', + 'Read a ChatGPT Desktop thread. Visible/recent turns use local CDP DOM harvest. full=true or a limit above the on-screen turns uses the Codex app-server (thread/read / resume); Desktop local: maps to the bare app-server id. DOM wheel crawl is only a fallback when app-server misses the thread. Result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -23,11 +23,16 @@ export default defineTool( additionalProperties: false, properties: { port: { type: 'number' }, - threadId: { type: 'string' }, + threadId: { + type: 'string', + description: + 'Desktop sidebar id (local:) or bare app-server thread id.', + }, limit: { type: 'number' }, full: { type: 'boolean', - description: 'When true, wheel-crawl older history (slow). Default false = visible turns only.', + description: + 'When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.', }, openTimeoutMs: { type: 'number', diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx index c03c81e..43f13ac 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop send', description: - 'Send a message in ChatGPT Desktop via local CDP: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Falls back to app-server send when CDP is down and threadId is set.', + 'Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.', annotations: { readOnlyHint: false }, inputSchema, resultSchema, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx index e3308d0..618b749 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop status', description: - 'Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server fallback is available. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.', + 'Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx index b865b11..79f88f2 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop wait for reply', description: - 'Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). Falls back to app-server polling when CDP is unreachable.', + 'Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index 60b9aa7..8a814cd 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -178,6 +178,85 @@ describe('chatgpt-desktop loopback + relaunch helpers', () => { }); }); +describe('chatgpt-desktop thread id mapping', () => { + it('maps local: ↔ app-server bare ids; temp rows do not map', async () => { + const { + LOCAL_THREAD_ID_PREFIX, + TEMP_THREAD_ID_PREFIX, + appServerThreadIdCandidates, + isTemporaryDesktopThreadId, + threadIdsEquivalent, + toAppServerThreadId, + toDesktopThreadId, + } = await import('../../src/core/chatgpt-desktop/index.js'); + + const bare = '11111111-1111-1111-1111-111111111111'; + const local = `${LOCAL_THREAD_ID_PREFIX}${bare}`; + expect(toAppServerThreadId(local)).toBe(bare); + expect(toAppServerThreadId(bare)).toBe(bare); + expect(toDesktopThreadId(bare)).toBe(local); + expect(toDesktopThreadId(local)).toBe(local); + expect(threadIdsEquivalent(local, bare)).toBe(true); + expect(appServerThreadIdCandidates(local)[0]).toBe(bare); + expect(appServerThreadIdCandidates(local)).toContain(local); + + const temp = `${TEMP_THREAD_ID_PREFIX}deadbeef`; + expect(isTemporaryDesktopThreadId(temp)).toBe(true); + expect(toAppServerThreadId(temp)).toBeNull(); + expect(appServerThreadIdCandidates(temp)).toEqual([]); + }); + + it('mergeThreadLists overlays CDP pinned/selected/project onto app-server rows', async () => { + const { mergeThreadLists } = await import('../../src/core/chatgpt-desktop/facade.js'); + const merged = mergeThreadLists( + { + backend: 'app-server', + limit: 10, + threads: [ + { + threadId: 'local:11111111-1111-1111-1111-111111111111', + title: 'from app-server', + pinned: false, + selected: false, + kind: 'codex', + }, + ], + }, + { + backend: 'cdp', + limit: 10, + threads: [ + { + threadId: 'local:11111111-1111-1111-1111-111111111111', + title: 'sidebar title', + pinned: true, + selected: true, + kind: 'local', + project: 'Launch', + }, + { + threadId: 'local:client-new-thread:temp', + title: 'draft', + pinned: false, + selected: true, + kind: 'local', + }, + ], + }, + ); + expect(merged.backend).toBe('app-server'); + expect(merged.threads[0]).toMatchObject({ + threadId: 'local:11111111-1111-1111-1111-111111111111', + title: 'from app-server', + pinned: true, + selected: true, + kind: 'local', + project: 'Launch', + }); + expect(merged.threads.some((t) => t.threadId === 'local:client-new-thread:temp')).toBe(true); + }); +}); + describe('chatgpt-desktop MCP tools', () => { it('registers the five chatgpt_desktop_* tools on the grok-bot server', async () => { const surface = await listMcpSurface({ server: 'grok-bot' }); @@ -332,34 +411,72 @@ describe('chatgpt-desktop CLI', () => { }); }); -describe('chatgpt-desktop CDP→app-server fallback', () => { - it('prefers CDP, then reuses app-server fallbacks with backend tagging', async () => { +describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => { + it('lists via app-server (merged with CDP), deep-reads via app-server, keeps send/wait on CDP', async () => { const calls: string[] = []; - const unreachable = new CdpUnreachableError('CDP down'); const cdp = fakeAdapter({ async connect() { calls.push('cdp.connect'); - throw unreachable; }, - async listThreads() { + async listThreads({ limit = 50 } = {}) { calls.push('cdp.listThreads'); - throw unreachable; + return { + backend: 'cdp', + limit, + threads: [ + { + threadId: 'local:11111111-1111-1111-1111-111111111111', + title: 'sidebar', + pinned: true, + selected: true, + kind: 'local', + project: 'Launch', + }, + ], + }; }, - async readThread() { - calls.push('cdp.readThread'); - throw unreachable; + async readThread({ threadId, limit = 100, full = false }) { + calls.push(`cdp.readThread:${full ? 'full' : 'visible'}`); + return { + threadId, + backend: 'cdp', + limit, + full, + turns: full + ? [ + { turnKey: 'old', role: 'user' as const, text: 'wheel' }, + { turnKey: 'new', role: 'assistant' as const, text: 'wheel-reply' }, + ] + : [{ turnKey: 'visible', role: 'assistant' as const, text: 'on screen' }], + }; }, - async sendMessage() { + async sendMessage({ threadId, text }) { calls.push('cdp.sendMessage'); - throw unreachable; + return { + threadId: threadId ?? 'local:client-new-thread:x', + backend: 'cdp', + experimental: false, + delivery: 'accepted' as const, + message: text, + }; + }, + async waitForReply({ threadId }) { + calls.push('cdp.waitForReply'); + return { + threadId: threadId ?? 'unknown', + reply: 'ok', + backend: 'cdp', + experimental: false, + delivery: 'replied' as const, + }; }, async status() { return { - reachable: false, + reachable: true, port: 9222, - host: '127.0.0.1', - message: 'CDP down', - exitCode: 1, + host: '127.0.0.1' as const, + message: 'ok', + exitCode: 0 as const, }; }, }); @@ -372,7 +489,7 @@ describe('chatgpt-desktop CDP→app-server fallback', () => { limit, threads: [ { - threadId: 'codex-1', + threadId: 'local:11111111-1111-1111-1111-111111111111', title: 'from app-server', pinned: false, selected: false, @@ -388,56 +505,183 @@ describe('chatgpt-desktop CDP→app-server fallback', () => { backend: 'app-server', limit, full, - turns: [{ turnKey: 't1', role: 'assistant', text: 'fallback reply' }], - }; - }, - sendMessage: async ({ threadId, text }) => { - calls.push('app-server.sendMessage'); - return { - threadId: threadId ?? 'missing', - backend: 'app-server', - experimental: false, - delivery: 'accepted', - message: text, + turns: [ + { turnKey: 't1', role: 'user', text: 'hello' }, + { turnKey: 't2', role: 'assistant', text: 'deep history' }, + ], }; }, - waitForReply: async ({ threadId }) => ({ - threadId: threadId ?? 'codex-1', - reply: 'fallback reply', - backend: 'app-server', - experimental: false, - delivery: 'replied' as const, - }), openThread: async (threadId) => ({ threadId, backend: 'app-server' as const }), statusProbe: async () => ({ reachable: true, mode: 'daemon', socketPath: '/tmp/fake.sock' }), }); const listed = await facade.listThreads({ limit: 5 }); - expect(listed).toMatchObject({ backend: 'app-server', threads: [{ threadId: 'codex-1' }] }); + expect(listed).toMatchObject({ + backend: 'app-server', + threads: [ + { + threadId: 'local:11111111-1111-1111-1111-111111111111', + title: 'from app-server', + pinned: true, + selected: true, + project: 'Launch', + }, + ], + }); + + // limit 100 > one visible turn → escalate to app-server + const deep = await facade.readThread({ + threadId: 'local:11111111-1111-1111-1111-111111111111', + limit: 100, + }); + expect(deep).toMatchObject({ backend: 'app-server', turns: [{ text: 'hello' }, { text: 'deep history' }] }); + + // full=true → app-server without requiring a visible undershoot + const full = await facade.readThread({ + threadId: 'local:11111111-1111-1111-1111-111111111111', + full: true, + }); + expect(full.backend).toBe('app-server'); + + // small limit satisfied by visible CDP harvest + const visible = await facade.readThread({ + threadId: 'local:11111111-1111-1111-1111-111111111111', + limit: 1, + }); + expect(visible).toMatchObject({ backend: 'cdp', turns: [{ text: 'on screen' }] }); + + const sent = await facade.sendMessage({ threadId: 'local:11111111-1111-1111-1111-111111111111', text: 'hi' }); + expect(sent).toMatchObject({ backend: 'cdp', delivery: 'accepted' }); + + const waited = await facade.waitForReply({ threadId: 'local:11111111-1111-1111-1111-111111111111' }); + expect(waited).toMatchObject({ backend: 'cdp', delivery: 'replied' }); + + expect(calls).toEqual([ + 'app-server.listThreads', + 'cdp.connect', + 'cdp.listThreads', + 'cdp.readThread:visible', + 'app-server.readThread', + 'app-server.readThread', + 'cdp.readThread:visible', + 'cdp.sendMessage', + 'cdp.waitForReply', + ]); + }); + + it('falls back to CDP wheel crawl when app-server deep-read fails', async () => { + const calls: string[] = []; + const facade = new ChatGptDesktopFacade( + fakeAdapter({ + async connect() { + calls.push('cdp.connect'); + }, + async readThread({ threadId, limit = 100, full = false }) { + calls.push(`cdp.readThread:${full ? 'full' : 'visible'}`); + return { + threadId, + backend: 'cdp', + limit, + full, + turns: [{ turnKey: 'w', role: 'assistant', text: 'from wheel' }], + }; + }, + }), + 9222, + { + listThreads: async () => ({ backend: 'app-server', limit: 1, threads: [] }), + readThread: async () => { + calls.push('app-server.readThread'); + throw new Error('unknown thread'); + }, + openThread: async () => { + throw new Error('unused'); + }, + statusProbe: async () => ({ reachable: false }), + }, + ); + + const read = await facade.readThread({ + threadId: 'local:11111111-1111-1111-1111-111111111111', + full: true, + }); + expect(read).toMatchObject({ backend: 'cdp', turns: [{ text: 'from wheel' }] }); + expect(calls).toEqual(['cdp.connect', 'app-server.readThread', 'cdp.readThread:full']); + }); + + it('does not fall back send/wait to app-server when CDP is down', async () => { + const unreachable = new CdpUnreachableError('CDP down'); + const facade = new ChatGptDesktopFacade( + fakeAdapter({ + async connect() { + throw unreachable; + }, + async sendMessage() { + throw unreachable; + }, + async waitForReply() { + throw unreachable; + }, + async status() { + return { + reachable: false, + port: 9222, + host: '127.0.0.1', + message: 'CDP down', + exitCode: 1, + }; + }, + }), + 9222, + { + listThreads: async ({ limit = 50 } = {}) => ({ + backend: 'app-server', + limit, + threads: [ + { + threadId: 'local:codex-1', + title: 'from app-server', + pinned: false, + selected: false, + kind: 'codex', + }, + ], + }), + readThread: async ({ threadId, limit = 100, full = false }) => ({ + threadId, + backend: 'app-server', + limit, + full, + turns: [{ turnKey: 't1', role: 'assistant', text: 'fallback reply' }], + }), + openThread: async (threadId) => ({ threadId, backend: 'app-server' as const }), + statusProbe: async () => ({ reachable: true, mode: 'daemon', socketPath: '/tmp/fake.sock' }), + }, + ); + + const listed = await facade.listThreads({ limit: 5 }); + expect(listed).toMatchObject({ backend: 'app-server', threads: [{ threadId: 'local:codex-1' }] }); - const read = await facade.readThread({ threadId: 'codex-1' }); + const read = await facade.readThread({ threadId: 'local:codex-1', full: true }); expect(read).toMatchObject({ backend: 'app-server', turns: [{ text: 'fallback reply' }] }); - const sent = await facade.sendMessage({ threadId: 'codex-1', text: 'hi' }); - expect(sent).toMatchObject({ backend: 'app-server', delivery: 'accepted' }); + await expect(facade.sendMessage({ threadId: 'local:codex-1', text: 'hi' })).rejects.toBeInstanceOf( + CdpUnreachableError, + ); + await expect(facade.waitForReply({ threadId: 'local:codex-1' })).rejects.toBeInstanceOf( + CdpUnreachableError, + ); const status = await facade.status(); expect(status).toMatchObject({ reachable: true, appServerFallback: { reachable: true, mode: 'daemon' }, - message: 'CDP unreachable; Codex app-server fallback is available', + message: 'CDP unreachable; Codex app-server available for list/deep-read', exitCode: 0, }); - - expect(calls.filter((c) => c.startsWith('app-server'))).toEqual([ - 'app-server.listThreads', - 'app-server.readThread', - 'app-server.sendMessage', - ]); - expect(calls.some((c) => c.startsWith('cdp.'))).toBe(true); }); - it('does not fall back for NotImplemented DOM gaps', async () => { + it('keeps app-server list when CDP merge hits NotImplemented', async () => { const facade = new ChatGptDesktopFacade( fakeAdapter({ async connect() {}, @@ -447,25 +691,33 @@ describe('chatgpt-desktop CDP→app-server fallback', () => { }), 9222, { - listThreads: async () => { - throw new Error('app-server should not run'); - }, + listThreads: async ({ limit = 50 } = {}) => ({ + backend: 'app-server', + limit, + threads: [ + { + threadId: 'local:codex-1', + title: 'from app-server', + pinned: false, + selected: false, + kind: 'codex', + }, + ], + }), readThread: async () => { throw new Error('unused'); }, - sendMessage: async () => { - throw new Error('unused'); - }, - waitForReply: async () => { - throw new Error('unused'); - }, openThread: async () => { throw new Error('unused'); }, statusProbe: async () => ({ reachable: false }), }, ); - await expect(facade.listThreads()).rejects.toBeInstanceOf(NotImplementedError); + const listed = await facade.listThreads(); + expect(listed).toMatchObject({ + backend: 'app-server', + threads: [{ threadId: 'local:codex-1' }], + }); }); }); From f800045ae45a404bcfebdfa857379dcd97f509a9 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 01:06:57 +0000 Subject: [PATCH 08/26] chore: retrigger Package CI for app-server deep-read redesign Co-authored-by: Zack Jackson From bf0275cb0ed9d3176584d1277e307423de64f30e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 01:18:12 +0000 Subject: [PATCH 09/26] feat: app-server list/search/read per 0.158.0; fix modelProviders Strip local: before app-server RPCs. Read via thread/read metadata plus thread/turns/list (itemsView full); never resume for reads. List and codex list-threads pass modelProviders:[]. Surface richer thread fields, remote-thread typed errors, and search. CDP keeps send/wait/selected. Co-authored-by: Zack Jackson --- .changeset/chatgpt-desktop-cdp.md | 2 +- README.md | 5 +- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 904 ++++++++++++----- artifact/bin/gbot.mjs | 941 +++++++++++++----- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 832 ++++++++++++---- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 819 +++++++++++---- artifact/scripts/gbot-relay.mjs | 16 +- docs/chatgpt-desktop-cdp.md | 77 +- src/cli/chatgpt-desktop/read.tsx | 2 +- src/cli/chatgpt-desktop/search.tsx | 46 + src/core/chatgpt-desktop/adapter.ts | 5 + .../chatgpt-desktop/app-server-fallback.ts | 450 ++++++--- src/core/chatgpt-desktop/errors.ts | 25 + src/core/chatgpt-desktop/facade.ts | 103 +- src/core/chatgpt-desktop/index.ts | 11 + src/core/chatgpt-desktop/remote-threads.ts | 75 ++ src/core/chatgpt-desktop/routes.ts | 44 +- src/core/chatgpt-desktop/thread-ids.ts | 42 +- src/core/chatgpt-desktop/types.ts | 30 +- src/core/codex-bridge.js | 26 +- .../tools/chatgpt_desktop_list_threads.tsx | 2 +- .../tools/chatgpt_desktop_read_thread.tsx | 4 +- .../tools/chatgpt_desktop_search_threads.tsx | 39 + test/codex-bridge.test.js | 133 ++- test/host-tool-inventory.test.js | 1 + tests/route-unit/chatgpt-desktop.test.ts | 186 ++-- tests/route-unit/tools.test.ts | 2 +- 29 files changed, 3619 insertions(+), 1207 deletions(-) create mode 100644 src/cli/chatgpt-desktop/search.tsx create mode 100644 src/core/chatgpt-desktop/remote-threads.ts create mode 100644 src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx diff --git a/.changeset/chatgpt-desktop-cdp.md b/.changeset/chatgpt-desktop-cdp.md index 08dfd6b..0ea8c8f 100644 --- a/.changeset/chatgpt-desktop-cdp.md +++ b/.changeset/chatgpt-desktop-cdp.md @@ -2,4 +2,4 @@ "grok-bot-cli": minor --- -Scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools (`chatgpt_desktop_*`, `gbot chatgpt-desktop`). Visible reads stay on CDP; deep/full history and thread listing prefer the existing Codex app-server client (`local:` ↔ bare thread id), with DOM wheel crawl as last-resort fallback. Send / new-thread / wait stay on CDP. Results report `backend`. +Scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools (`chatgpt_desktop_*`, `gbot chatgpt-desktop`). List/search/read prefer Codex app-server 0.158.0 (`modelProviders: []`, `thread/read` + `thread/turns/list`; no resume for reads). Send/wait/selected stay on CDP. Fixes `gbot codex list-threads` missing other providers. Reports `backend`. diff --git a/README.md b/README.md index c0074b1..69eac6b 100644 --- a/README.md +++ b/README.md @@ -230,19 +230,20 @@ osascript -e 'tell application "ChatGPT" to quit' \ && open -a /Applications/ChatGPT.app --args --remote-debugging-port=9222 gbot chatgpt-desktop status gbot chatgpt-desktop threads --limit 20 +gbot chatgpt-desktop search "launch" gbot chatgpt-desktop read gbot chatgpt-desktop read --full --limit 200 gbot chatgpt-desktop send --project Launch "hello" gbot chatgpt-desktop send --thread-id "hello" ``` -MCP tools: `chatgpt_desktop_status`, `chatgpt_desktop_list_threads`, `chatgpt_desktop_read_thread`, `chatgpt_desktop_send`, `chatgpt_desktop_wait_reply`. New chats prefer `project` (“Start new chat in …”); `wait_reply` resolves the real conversation id. Visible/recent reads stay on CDP; `--full` or a limit above the on-screen turns uses the Codex app-server (`thread/read` / resume) — DOM wheel crawl is last-resort only. List prefers app-server and merges CDP sidebar fields (`pinned`/`selected`/`project`). Send / new-thread / wait stay on CDP. Desktop `local:` maps to app-server thread ids. Results report `backend: "cdp" | "app-server"`. Details: [docs/chatgpt-desktop-cdp.md](docs/chatgpt-desktop-cdp.md). +MCP tools: `chatgpt_desktop_status`, `chatgpt_desktop_list_threads`, `chatgpt_desktop_search_threads`, `chatgpt_desktop_read_thread`, `chatgpt_desktop_send`, `chatgpt_desktop_wait_reply`. List/search/read prefer the Codex app-server (`thread/list` with `modelProviders: []`, `thread/read` + `thread/turns/list`; never `thread/resume` for reads). Send / new-thread / wait / selected-thread stay on CDP; DOM read is fallback only. Desktop `local:` strips to the bare app-server id. Results report `backend: "cdp" | "app-server"`. Details: [docs/chatgpt-desktop-cdp.md](docs/chatgpt-desktop-cdp.md). **Status contract (`gbot codex status --json`).** `reachable` is endpoint reachability only. `socketState` is `socket`, `absent`, `permission-denied`, or `not-a-socket`; `mode` is `daemon` for a usable daemon, otherwise the failure: `socket-absent`, `permission-denied` (the file or the connect refused this user), `not-a-socket`, `connect-failed` (socket present, nothing completed the WebSocket upgrade), `handshake-failed` (upgrade or `initialize` failed), `windows-unsupported`, or `bad-response` (reachable, but `initialize` returned something off-schema — `reachable` stays `true`). `schema.compatibility` is `exact` when the daemon reports the pinned version, `unverified` when it differs (methods usually survive upgrades, but the shapes are not re-checked), or `unknown`. `cliVersionProbe` reports whether `codex --version` answered (`ok`, `missing`, `timeout` after 3 s, `error`). The document is always written to stdout and includes `exitCode`; it is `0` only for a usable daemon. `desktopShimConfigured` is true when the installed wrapper is selected by Desktop-facing `CODEX_CLI_PATH` (the GUI domain on macOS). This describes configuration for future launches; a running Desktop may not have inherited it, and the wrapper may have fallen back to stock Codex. `desktopAttached` is `"private-stdio"` when a Desktop-bundled app-server process is observed, otherwise `"unknown"`. That process observation and shim configuration can both be present. Neither a configured shim nor a reachable daemon proves Desktop is attached to that daemon. Verify actual attachment with a controlled shared-thread interaction and matching thread/turn IDs. -**Thread discovery.** `list-threads --limit N` (1–200) pages with the opaque `--cursor` from the previous `nextCursor`; JSON keeps the cursor verbatim, text output prints a sanitized `more: --cursor …` hint. Text fields are stripped of terminal control sequences in both outputs (single-line fields also lose line breaks; `preview` keeps its newlines; a structured `source` such as `{ "custom": … }` passes through unchanged), `status` is one of `notLoaded | idle | active | systemError | unknown`, and non-numeric `updatedAt` becomes `null`. Unknown arguments are rejected before the socket is touched; a response that does not match the pinned schema (including an entry without a string `id`) fails with `reason: "bad-response"`. +**Thread discovery.** `list-threads --limit N` (1–200) pages with the opaque `--cursor` from the previous `nextCursor`; JSON keeps the cursor verbatim, text output prints a sanitized `more: --cursor …` hint. Requests pass `modelProviders: []` so threads from every provider appear (the daemon otherwise filters to the current provider) and `useStateDbOnly: true` for a fast state-DB listing. Text fields are stripped of terminal control sequences in both outputs (single-line fields also lose line breaks; `preview` keeps its newlines; a structured `source` such as `{ "custom": … }` passes through unchanged), `status` is one of `notLoaded | idle | active | systemError | unknown`, and non-numeric `updatedAt` / `createdAt` become `null`. Extra fields when present: `section`, `projectId`, `modelProvider`, `model`, `originator`. Unknown arguments are rejected before the socket is touched; a response that does not match the pinned schema (including an entry without a string `id`) fails with `reason: "bad-response"`. **Routes, attribution, and loops.** `gbot codex send` runs on the machine that owns `CODEX_HOME`, as the user who owns the socket, with that user's Codex credentials; the socket path comes only from `CODEX_HOME` or `CODEX_APP_SERVER_SOCK`, never from the message or an agent-supplied argument. gbot has no remote transport. A cloud-hosted Grok Bot on the box cannot reach a desktop socket at `/home/box/.codex/...` — use Grok Bot Shell with a machineId to run `gbot` on the user's registered machine (after `codex app-server daemon start` / bootstrap there). `GROK_BOT_CODEX_THREADS=id,id` lets the operator pin `send` to approved threads (`reason: "route-not-allowed"` otherwise). Every send gets a delivery envelope: `messageId` (also sent as Codex's native `clientUserMessageId`), `correlationId` (defaults to the message id), optional `replyTo`, and `hop`. A reply passes the original correlation id and `hop` + 1: diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index d7e468b..2952302 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"802e40d8872e9aa4237beb53e0b90047f2e699242153b43220688be49cd8414a"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"e447bd2012a36e0e68c31036d5d95a40216b4194d375c5879b063123f64cc9d5"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"732ae5614b7b68c593f2b43847cb4700581e1dee29cff84306d7c92d5915a636"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"4fc6fde4498e16a5ef22138dc03e8b46f7d42fac4a2aedf63a8f223ddd7d0c7c"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"3722353a3796ef633fe18957490e66a1199f8d6fbc67b3153d00890e17d804a6"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"0f79d51bb84d33a62274d6aa057e4b6a2f026e360bf7f4f41ca4a43084e0f22e"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"2959f151e202868e825754147def8bc1bad29fa8166708c1dceca8c7393b7de7"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"e9f097dd1f8925d7cb71f813e2ac786de0a06b3fd38786cfc857db6ee3156a48"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"cb1b5f1beee1135f846f1e1ba0caf78a4e8cba7abc29b12cdbb110cd05b44e25"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 1536035..1658fd5 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"933aff6b4167b1601d57c8204e0fa1f7a0ba05fb5836b45ed7e4417c9c10ddbb","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"c69abd855ead0de2b65548933ee22d0581ead66bab93bc3fd75bbc069e75705c","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"3f32dc3e997e0a2a7eae42f11838f7f42c450c70b90a8eda82a7e91c62423e40"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"6ea39a60be58f4080186e3d2713df71b8239d4d109231c3824541bff0b3f5c5f"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"8582da3110017051ec4ca4526dab606311538d14942469e8fad53e4a4c7a3e23"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"e56a9e36bd4211aa3563530e8bbd58ea6aae80734c4fae02d12b4c24e61613eb"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"63201b6028899f4f2b9f63381a8536c5fba09586ea81c8cf857bcaab687e9249"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"cb17b333ac3a50988b6146f6e9b1d76bb2805c8c5073692269f3bd424a504891"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"64af4259dc9be7bdc22224935ab548a51e4e82ccb26a4bb40c39085b9efbda06"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"8a45cab48d9f02da4fa2118e0a238696ab2f4ee198faff45ac64580c1f687d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"98edba7908cecffb141018bc358074f2785baf84bd76c4e9564843d48ad9e2dd"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"56a8ea6c9618831131cdf16bb60e1b0e764a4f8c72c9557d926db94f5b7090b8"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"30bec04c550f1eb9cd09801fc565c341d220e43ffcc134809f7ed69e169f00db"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"f7cd7d29d64677f5222896dbe742afff52644307a787cf4065c3b1acb3cb27b1"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"1e0ae41608486b1950ccf66729f7fce28585a89121606c6bac81485d3dd04f6d"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"9aa8e429ec8e23784d6b5aac62fff893bf24a1b31caea82d0c58ec1553480b76"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"85ea126d588ebd6731fa842df897082fa728bbb93f20efa660e78a133a6eaa36"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"7dfb0e5cd0117ac38650f83ce257e35f77fe71398b5e5e48c695abbf4d2d7e6c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"1c22eddde86abc035751277d75109e4ad8a62941634dd004f313e8ea6e6a688b"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"7d4071ed41a4c0b0814f87bb18d3802235a9c26ad82016b73375aa590f8de8b0"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"7f21f53f2ba99894d65b3dee8518f9483805fc2bda9444939a5a1fa44d74df30"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"56454a78aaea180d78e8cd62385ef66261f1748b593aa5165e587d5975205af4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"ee26dc07b4baade26d8154ed7b4cb69c24285f2997f016bbfb8607e728e7e6bb"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"31e48f236341f3102b94cd35fb2aa406a54a56cd86b2006452ec569ad503640d"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7bfaf1abfe75bc5c2167d9053c76d33ed830a083780d2dc3017492ec3c44799d"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":21751,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"e6212f639e4817cd0294212f671bab2a604ec4eaede4b20e6e25cc08c2b26bfd"},{"bytes":1439316,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"802e40d8872e9aa4237beb53e0b90047f2e699242153b43220688be49cd8414a"},{"bytes":2297844,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"e447bd2012a36e0e68c31036d5d95a40216b4194d375c5879b063123f64cc9d5"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1355572,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"732ae5614b7b68c593f2b43847cb4700581e1dee29cff84306d7c92d5915a636"},{"bytes":3181472,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"4fc6fde4498e16a5ef22138dc03e8b46f7d42fac4a2aedf63a8f223ddd7d0c7c"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281157,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"e2ce16be5d3a351d0dd03238bc6fe08f6e18edee6d7034905fbd9aead295b3c5"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread. Visible turns via CDP; --full / deep history via app-server (wheel crawl last-resort).","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.","exitCode":"result","options":[{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread. Visible turns via CDP; --full / deep history via app-server (wheel crawl last-resort).","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"528b746c2d3913bf33a1fbee1d999fc136647113ac4f8eb4505d0ba384cfddd6","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via the Codex app-server when available (thread/list), merging CDP-only sidebar fields (pinned, selected, project, kind) when CDP is connected. Desktop local: maps to bare app-server ids. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread. Visible/recent turns use local CDP DOM harvest. full=true or a limit above the on-screen turns uses the Codex app-server (thread/read / resume); Desktop local: maps to the bare app-server id. DOM wheel crawl is only a fallback when app-server misses the thread. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"53d64ca80f7cb54b52a9c260bb71eaec4b275abd49fa739ad9ad7b5af2b7db2d","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"be4c37b608d956c615570d4a90edb128b682742262b8b62c41ee7c54d06c92bd","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"b76cad662fd181e66ac6864b4f59d1bf1b1dfc58cbe2ea20906770c7467dab68"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"8048333f655b419d49e061b80d8adba0bfa319820ec6b163e9b98c13d97172cb"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"f7c39813e719de53abbd4bd4dc99e3cc606253b3235ee04a9b346582bff771ce"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"42dba18d7b3223dbe5a96cd6fee98bd0f72f7977f5e6a801c6553f315ff94af7"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"63201b6028899f4f2b9f63381a8536c5fba09586ea81c8cf857bcaab687e9249"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"7bd4aa75c099c06f794a1d6a42de080df36dc7cdc47834b5d1b7e152d927610d"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"7332ee5b07f5c05356feac0887604b242d1b3a642b7f9a953fa0496124000f73"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"8a45cab48d9f02da4fa2118e0a238696ab2f4ee198faff45ac64580c1f687d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"98edba7908cecffb141018bc358074f2785baf84bd76c4e9564843d48ad9e2dd"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"6ef54c4ddb0cfccff782131120903cf8aeffde9f869887336ff7388216200201"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"fff92ea6fec1d8822f46e9d3d5e088c9c0d1f2c87773a7ec2c0e61b2b5f99535"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"029776eba4027c85f5815cf502a39fa3b7ff7c186ac992b7795f89a1b1d2a6be"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"164b99937f55ba5f4c56fd1e3bb251053c57867d93b6c641476454b527d9d5e1"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"e1498e9a15d29385dd37ca3b9395e38305d2dbdd2ae10426866f6170285c31f4"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"4c6785207b4216b2815068f68d438b3cbb6e480f684a661dc8f25d5e4b053e1b"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"9bb12f38a482e90f3a2303fb51d32e5ede3e4ccb40a42d95dded4a778b1198ca"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"655891a361725bad8463a333f9650e9ff8f70512a750c73be93a56326bd62cab"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"0ff101c427c38c9dfd699c1013c5cac4c2e5b25a3bf64602ea53c29b79363700"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"26166d29f71b43924395ef84567612093ba89d22a69c5cb4551d843a291d6689"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"0922ecf1c7a3823cd3efc7d46554b5e6e284329f0893d7ad2e1cf6263eadf67c"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"7f21f53f2ba99894d65b3dee8518f9483805fc2bda9444939a5a1fa44d74df30"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"b66856473b10327fc5c661d684b773ca0e4674821130a3072f198d498f56d8e6"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"d4282ddc4619978d0a0cf76e898d9495fc058935832a42fc8a7a14c56fa1566a"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"33f576dde77cd7cb0eb8bdad7dda58b63ec448a302b48966740ef21cdbab47e5"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22291,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"9f817266b386e10e6a8948aa180f83c7543c4b37cb1025d894883cd061362e9e"},{"bytes":1457989,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"3722353a3796ef633fe18957490e66a1199f8d6fbc67b3153d00890e17d804a6"},{"bytes":2318195,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"0f79d51bb84d33a62274d6aa057e4b6a2f026e360bf7f4f41ca4a43084e0f22e"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1375596,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"2959f151e202868e825754147def8bc1bad29fa8166708c1dceca8c7393b7de7"},{"bytes":3201729,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"e9f097dd1f8925d7cb71f813e2ac786de0a06b3fd38786cfc857db6ee3156a48"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281817,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"cb1b5f1beee1135f846f1e1ba0caf78a4e8cba7abc29b12cdbb110cd05b44e25"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.","exitCode":"result","options":[{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.","exitCode":"result","options":[{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum matches (1-200).","type":"number"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"6f7e748cd7d78a6eca00241f8c917b2bf2bb79e5e5af1d19701628b5d8bc3909","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads via app-server thread/list (modelProviders:[], useStateDbOnly). Merges CDP-only UI fields (selected, pinned overlay) when CDP is connected. Desktop local: strips to bare app-server ids. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. DOM harvest/wheel is fallback only when app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server (thread/list with modelProviders:[]), matching name/preview/cwd/project/model fields. Merges CDP selected/pinned when connected. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum matches (1-200).","type":"number"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index b8ba2b1..cb3f7ab 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -8616,7 +8616,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Read a ChatGPT Desktop thread. Visible turns via CDP; --full / deep history via app-server (wheel crawl last-resort).', + description: 'Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.', exitCode: 'result', positionals: [ 'threadId' @@ -8685,6 +8685,62 @@ var __webpack_modules__ = { inputSchema: inputSchema }); }, + "./src/cli/chatgpt-desktop/search.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const config = { + description: 'Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.', + exitCode: 'result', + positionals: [ + 'query' + ], + inputJsonSchema: { + additionalProperties: false, + properties: { + limit: { + default: 50, + description: 'Max matches (1-200)', + type: 'number' + }, + port: { + description: 'Local CDP port', + type: 'number' + }, + query: { + type: 'string' + } + }, + required: [ + 'query' + ], + type: 'object' + } + }; + const inputSchema = zod__rspack_import_2.Ikc({ + limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), + port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), + query: zod__rspack_import_2.YjP().min(1).max(512) + }).strict(); + async function chatgptDesktopSearch({ input }) { + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.zg)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out) + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>chatgptDesktopSearch, + resultSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_1.FD + }, { + config: config, + inputSchema: inputSchema + }); + }, "./src/cli/chatgpt-desktop/send.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); @@ -11130,79 +11186,74 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/app-server-fallback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); - var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); - async function appServerListThreads({ limit = 50 } = {}) { + var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _remote_threads_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + async function appServerListThreads({ limit = 50, cursor } = {}) { const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit + limit, + cursor }); return { backend: 'app-server', limit: out.limit, - threads: out.threads.map((thread)=>{ - const bare = String(thread.id ?? ''); - return { - threadId: bare ? (0, _thread_ids_js__rspack_import_1.BS)(bare) : '', - title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), - pinned: false, - selected: false, - kind: 'codex' - }; - }) + nextCursor: out.nextCursor ?? null, + threads: out.threads.map(mapListedThread) }; } - async function appServerReadThread({ threadId, limit = 100, full = false }) { - const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); - if (candidates.length === 0) { - throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); + async function appServerSearchThreads({ query, limit = 50 }) { + const needle = query.trim().toLowerCase(); + if (!needle) { + return appServerListThreads({ + limit + }); } - const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); - try { - let lastError; - for (const candidate of candidates){ - try { - const turns = await readTurnsForId(client, candidate, { - limit, - full - }); - return { - threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), - turns, - backend: 'app-server', - limit, - full - }; - } catch (error) { - lastError = error; - } + const matched = []; + let cursor; + for(let page = 0; page < 20 && matched.length < limit; page++){ + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit: 200, + cursor + }); + for (const thread of out.threads){ + const mapped = mapListedThread(thread); + if (threadMatchesQuery(mapped, needle)) matched.push(mapped); + if (matched.length >= limit) break; } - throw lastError instanceof Error ? lastError : new Error(`app-server thread read failed for ${threadId}`); - } finally{ - client.close(); + if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + cursor = out.nextCursor; } + return { + backend: 'app-server', + limit, + query, + nextCursor: null, + threads: matched.slice(0, limit) + }; } - async function appServerOpenThread(threadId) { - const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); - if (candidates.length === 0) { - throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); - } + async function appServerReadThread({ threadId, limit = 100, full = false }) { + const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { - let lastError; - for (const candidate of candidates){ - try { - await client.request('thread/resume', { - threadId: candidate, - excludeTurns: true - }); - return { - threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), - backend: 'app-server' - }; - } catch (error) { - lastError = error; - } - } - throw lastError instanceof Error ? lastError : new Error(`app-server thread/resume failed for ${threadId}`); + const meta = await readThreadMetadata(client, bare); + const turns = await listTurnsFull(client, bare, { + limit, + full + }); + return { + threadId: (0, _thread_ids_js__rspack_import_3.BS)(bare), + turns, + backend: 'app-server', + limit, + full, + title: meta.title, + cwd: meta.cwd, + status: meta.status, + modelProvider: meta.modelProvider, + model: meta.model + }; + } catch (error) { + throw maybeRemoteThreadError(error, bare); } finally{ client.close(); } @@ -11215,32 +11266,110 @@ var __webpack_modules__ = { socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined }; } - async function readTurnsForId(client, threadId, { limit, full }) { + function mapListedThread(thread) { + const bare = String(thread.id ?? ''); + const section = thread.section && typeof thread.section.id === 'string' ? { + id: thread.section.id, + name: thread.section.name ?? null + } : null; + const pinned = section?.id === 'Pinned' || section?.name === 'Pinned' || false; + return { + threadId: bare ? (0, _thread_ids_js__rspack_import_3.BS)(bare) : '', + title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), + pinned, + selected: false, + kind: 'codex', + preview: typeof thread.preview === 'string' ? thread.preview : undefined, + cwd: thread.cwd ?? null, + createdAt: thread.createdAt ?? null, + updatedAt: thread.updatedAt ?? null, + section, + projectId: thread.projectId ?? null, + project: thread.projectId ?? undefined, + status: thread.status, + modelProvider: thread.modelProvider ?? null, + model: thread.model ?? null, + originator: thread.originator ?? null + }; + } + function threadMatchesQuery(thread, needle) { + const haystacks = [ + thread.threadId, + thread.title, + thread.preview, + thread.cwd, + thread.project, + thread.projectId, + thread.model, + thread.modelProvider, + thread.originator, + thread.section?.name, + thread.section?.id + ]; + return haystacks.some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } + async function readThreadMetadata(client, threadId) { try { const read = await client.request('thread/read', { threadId }); - const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - if (Array.isArray(raw) && raw.length > 0) { - return sliceTurns(normalizeTurns(raw), { - limit, - full + const thread = read.thread && typeof read.thread === 'object' ? read.thread : {}; + const statusObj = thread.status; + const statusType = statusObj && typeof statusObj === 'object' && typeof statusObj.type === 'string' ? String(statusObj.type) : typeof thread.status === 'string' ? thread.status : undefined; + return { + title: typeof thread.name === 'string' ? thread.name : typeof thread.preview === 'string' ? thread.preview : undefined, + cwd: typeof thread.cwd === 'string' ? thread.cwd : null, + status: statusType, + modelProvider: typeof thread.modelProvider === 'string' ? thread.modelProvider : null, + model: typeof thread.model === 'string' ? thread.model : null + }; + } catch (error) { + throw maybeRemoteThreadError(error, threadId); + } + } + async function listTurnsFull(client, threadId, { limit, full }) { + const collected = []; + let cursor; + try { + for(let page = 0; page < 40; page++){ + const result = await client.request('thread/turns/list', { + threadId, + limit: 100, + itemsView: 'full', + ...cursor ? { + cursor + } : {} }); + if (!Array.isArray(result.data)) { + throw new Error(`thread/turns/list missing data array for ${threadId}`); + } + collected.push(...result.data); + if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; + cursor = result.nextCursor; + if (!full && collected.length >= limit) break; } - } catch {} - try { - const resumed = await client.request('thread/resume', { - threadId, - excludeTurns: false - }); - const raw = resumed.thread?.turns ?? resumed.turns ?? resumed.thread?.items ?? []; - if (Array.isArray(raw) && raw.length > 0) { - return sliceTurns(normalizeTurns(raw), { + } catch (error) { + if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + if (collected.length === 0) { + return listTurnsFallback(client, threadId, { limit, full }); } - } catch {} + throw error; + } + if (collected.length === 0) { + return listTurnsFallback(client, threadId, { + limit, + full + }); + } + return sliceTurns(normalizeTurns(collected), { + limit, + full + }); + } + async function listTurnsFallback(client, threadId, { limit, full }) { for (const method of [ 'thread/turns/list', 'thread/items/list' @@ -11248,14 +11377,16 @@ var __webpack_modules__ = { try { const collected = []; let cursor; - for(let page = 0; page < 20; page++){ - const result = await client.request(method, { + for(let page = 0; page < 40; page++){ + const params = { threadId, limit: 100, ...cursor ? { cursor } : {} - }); + }; + if (method === 'thread/turns/list') params.itemsView = 'full'; + const result = await client.request(method, params); if (!Array.isArray(result.data)) break; collected.push(...result.data); if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; @@ -11268,7 +11399,9 @@ var __webpack_modules__ = { full }); } - } catch {} + } catch (error) { + if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + } } throw new Error(`app-server has no turn history for thread ${threadId}`); } @@ -11282,24 +11415,116 @@ var __webpack_modules__ = { for (const [index, item] of raw.entries()){ if (!item || typeof item !== 'object') continue; const row = item; - const text = typeof row.text === 'string' ? row.text : typeof row.content === 'string' ? row.content : ''; - const type = String(row.type ?? row.role ?? ''); - let role = 'assistant'; - if (/user/i.test(type)) role = 'user'; - else if (/status|system|reasoning/i.test(type) && !text) role = 'status'; - turns.push({ - turnKey: String(row.id ?? row.turnId ?? index), - role, - text - }); + const id = String(row.id ?? row.turnId ?? index); + const items = Array.isArray(row.items) ? row.items : null; + if (items) { + turns.push(normalizeTurnWithItems(id, row, items)); + continue; + } + turns.push(normalizeLeafItem(id, row)); } return turns; } + function normalizeTurnWithItems(id, row, items) { + let userText = ''; + let assistantText = ''; + let toolText = ''; + let reasoningText = ''; + for (const entry of items){ + if (!entry || typeof entry !== 'object') continue; + const item = entry; + const type = String(item.type ?? item.role ?? ''); + const text = extractText(item); + if (/user/i.test(type)) userText = joinText(userText, text); + else if (/agent|assistant|message/i.test(type) && !/reasoning|tool/i.test(type)) { + assistantText = joinText(assistantText, text); + } else if (/tool/i.test(type)) toolText = joinText(toolText, text || type); + else if (/reasoning/i.test(type)) reasoningText = joinText(reasoningText, text); + } + let role = 'assistant'; + let text = assistantText || userText; + if (userText && !assistantText) { + role = 'user'; + text = userText; + } else if (!userText && !assistantText && toolText) { + role = 'tool'; + text = toolText; + } else if (!userText && !assistantText && reasoningText) { + role = 'reasoning'; + text = reasoningText; + } + return { + turnKey: (0, _thread_ids_js__rspack_import_3.Sr)(id), + role, + text, + ...userText ? { + userText + } : {}, + ...assistantText ? { + assistantText + } : {}, + startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, + endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + }; + } + function normalizeLeafItem(id, row) { + const text = extractText(row); + const type = String(row.type ?? row.role ?? ''); + let role = 'assistant'; + if (/user/i.test(type)) role = 'user'; + else if (/tool/i.test(type)) role = 'tool'; + else if (/reasoning/i.test(type)) role = 'reasoning'; + else if (/status|system/i.test(type) && !text) role = 'status'; + return { + turnKey: (0, _thread_ids_js__rspack_import_3.Sr)(id), + role, + text, + startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, + endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + }; + } + function extractText(row) { + if (typeof row.text === 'string') return row.text; + if (typeof row.content === 'string') return row.content; + if (typeof row.preview === 'string') return row.preview; + return ''; + } + function joinText(left, right) { + if (!right) return left; + if (!left) return right; + return `${left}\n${right}`; + } + function isThreadNotLoaded(error) { + const message = errorMessage(error); + return /thread not loaded|not loaded|invalid thread id/i.test(message); + } + function maybeRemoteThreadError(error, threadId) { + const message = errorMessage(error); + if (/thread not loaded|not loaded/i.test(message)) { + const hostId = (0, _remote_threads_js__rspack_import_2.X)(threadId); + return new _errors_js__rspack_import_1.Rg(threadId, hostId); + } + if (error instanceof Error) return error; + return new Error(message || `app-server error for thread ${threadId}`); + } + function errorMessage(error) { + if (!error) return ''; + if (typeof error === 'string') return error; + if (error instanceof Error) return error.message; + if (typeof error === 'object' && error && 'message' in error) { + return String(error.message); + } + if (typeof error === 'object' && error && 'rpc' in error) { + const rpc = error.rpc; + if (rpc && typeof rpc.message === 'string') return rpc.message; + } + return String(error); + } __webpack_require__.d(__webpack_exports__, { Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, - dM: ()=>appServerStatusProbe, - zu: ()=>appServerOpenThread + aI: ()=>appServerSearchThreads, + dM: ()=>appServerStatusProbe }); }, "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -12171,8 +12396,23 @@ var __webpack_modules__ = { this.name = 'CdpUnreachableError'; } } + class RemoteThreadNotLoadedError extends Error { + code = 'REMOTE_THREAD_NOT_LOADED'; + delivery = 'rejected'; + reason = 'remote-thread-not-loaded'; + threadId; + hostId; + constructor(threadId, hostId = null){ + const owner = hostId ? `owned by remote-control host ${JSON.stringify(hostId)}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ` + `${owner}. SSH remoting is not implemented in this adapter yet.`); + this.name = 'RemoteThreadNotLoadedError'; + this.threadId = threadId; + this.hostId = hostId; + } + } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, + Rg: ()=>RemoteThreadNotLoadedError, c$: ()=>CdpHostRejectedError, sO: ()=>CdpUnreachableError }); @@ -12185,8 +12425,8 @@ var __webpack_modules__ = { var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, + searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, - openThread: _app_server_fallback_js__rspack_import_1.zu, statusProbe: _app_server_fallback_js__rspack_import_1.dM }; class ChatGptDesktopFacade { @@ -12244,30 +12484,45 @@ var __webpack_modules__ = { if (appError) throw appError; throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); } + async searchThreads(options) { + try { + const appList = await this.#fallbacks.searchThreads(options); + const cdpList = await this.#tryCdpList({ + limit: options.limit + }); + if (cdpList) return mergeThreadLists(appList, cdpList); + return appList; + } catch (appError) { + const cdpList = await this.#tryCdpList({ + limit: options.limit + }); + if (!cdpList) throw appError; + const needle = options.query.trim().toLowerCase(); + return { + ...cdpList, + query: options.query, + threads: cdpList.threads.filter((thread)=>{ + if (!needle) return true; + return [ + thread.title, + thread.threadId, + thread.project + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + }) + }; + } + } async readThread(options) { const limit = options.limit ?? 100; const full = options.full ?? false; - const cdpConnected = await this.#tryEnsureCdp(); if ((0, _thread_ids_js__rspack_import_4.vr)(options.threadId)) { - if (!cdpConnected) { - throw new _errors_js__rspack_import_2.sO(`ChatGPT Desktop temporary thread ${options.threadId} requires CDP`); - } + await this.#ensureCdp(); return this.#cdp.readThread({ ...options, limit, full }); } - if (cdpConnected && !full) { - const visible = await this.#cdp.readThread({ - ...options, - limit, - full: false - }); - if (limit <= visible.turns.length) { - return visible; - } - } try { return await this.#fallbacks.readThread({ threadId: options.threadId, @@ -12275,14 +12530,13 @@ var __webpack_modules__ = { full }); } catch (appError) { - if (cdpConnected) { - return this.#cdp.readThread({ - ...options, - limit, - full: true - }); - } - throw appError; + const cdpConnected = await this.#tryEnsureCdp(); + if (!cdpConnected) throw appError; + return this.#cdp.readThread({ + ...options, + limit, + full: full || true + }); } } async sendMessage(options) { @@ -12294,13 +12548,8 @@ var __webpack_modules__ = { return this.#cdp.waitForReply(options); } async openThread(threadId, options) { - try { - await this.#ensureCdp(); - return await this.#cdp.openThread(threadId, options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.openThread(threadId); - } + await this.#ensureCdp(); + return this.#cdp.openThread(threadId, options); } async status() { const cdpStatus = await this.#cdp.status(); @@ -12318,7 +12567,7 @@ var __webpack_modules__ = { port: this.#port, appServerFallback, reachable, - message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/deep-read' : cdpStatus.message, + message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/search/read' : cdpStatus.message, exitCode: reachable ? 0 : 1 }; } @@ -12343,6 +12592,18 @@ var __webpack_modules__ = { return false; } } + async #tryCdpList(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.listThreads(options); + } catch (error) { + if (isCdpFailure(error) || error instanceof _errors_js__rspack_import_2.EH) { + if (isCdpFailure(error)) this.#cdpConnected = false; + return null; + } + throw error; + } + } } function mergeThreadLists(appList, cdpList) { const cdpByKey = new Map(); @@ -12357,12 +12618,10 @@ var __webpack_modules__ = { return { ...thread, title: thread.title || cdp.title, - pinned: cdp.pinned, + pinned: thread.pinned || cdp.pinned, selected: cdp.selected, kind: cdp.kind || thread.kind, - ...cdp.project !== undefined ? { - project: cdp.project - } : {} + project: cdp.project ?? thread.project }; }); for (const thread of cdpList.threads){ @@ -12372,6 +12631,10 @@ var __webpack_modules__ = { return { backend: 'app-server', limit: appList.limit, + nextCursor: appList.nextCursor, + ...appList.query !== undefined ? { + query: appList.query + } : {}, threads: merged.slice(0, appList.limit) }; } @@ -12457,6 +12720,74 @@ var __webpack_modules__ = { tb: ()=>assertLoopbackHostname }); }, + "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var node_os__rspack_import_1 = __webpack_require__("node:os"); + var node_path__rspack_import_2 = __webpack_require__("node:path"); + var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; + function codexGlobalStatePath(env = process.env) { + const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); + return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); + } + function findRemoteThreadHostId(threadId, env = process.env) { + const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; + if (!bare) return null; + let raw; + try { + raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); + } catch { + return null; + } + let data; + try { + data = JSON.parse(raw); + } catch { + return null; + } + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + for (const [key, value] of Object.entries(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match) continue; + if (summariesIncludeThread(value, bare)) return match[1] ?? null; + } + return null; + } + function summariesIncludeThread(value, threadId) { + if (Array.isArray(value)) { + return value.some((entry)=>entryMentionsThread(entry, threadId)); + } + if (value && typeof value === 'object') { + const record = value; + if (threadId in record) return true; + if (Array.isArray(record.threads)) { + return record.threads.some((entry)=>entryMentionsThread(entry, threadId)); + } + if (Array.isArray(record.summaries)) { + return record.summaries.some((entry)=>entryMentionsThread(entry, threadId)); + } + return Object.values(record).some((entry)=>entryMentionsThread(entry, threadId)); + } + return false; + } + function entryMentionsThread(entry, threadId) { + if (typeof entry === 'string') return entry === threadId; + if (!entry || typeof entry !== 'object') return false; + const row = entry; + for (const key of [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]){ + if (row[key] === threadId) return true; + } + return false; + } + __webpack_require__.d(__webpack_exports__, { + X: ()=>findRemoteThreadHostId + }); + }, "./src/core/chatgpt-desktop/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_4 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _codex_contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); @@ -12471,6 +12802,11 @@ var __webpack_modules__ = { port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) }).strict(); + const searchThreadsSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + query: zod__rspack_import_4.YjP().min(1).max(512), + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + }).strict(); const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, @@ -12520,6 +12856,19 @@ var __webpack_modules__ = { exitCode: 1 }); } + if (error instanceof _errors_js__rspack_import_1.Rg) { + return asResult({ + delivery: error.delivery, + reason: error.reason, + code: error.code, + error: error.message, + threadId: error.threadId, + ...error.hostId ? { + hostId: error.hostId + } : {}, + exitCode: 1 + }); + } const base = (0, _codex_contract_js__rspack_import_0.DG)(error); if (error && typeof error === 'object' && 'code' in error) { return asResult({ @@ -12550,6 +12899,25 @@ var __webpack_modules__ = { return mapError(error); } } + async function searchThreadsOperation(input) { + try { + const out = await withAdapter(input.port, async (adapter)=>{ + if (typeof adapter.searchThreads !== 'function') { + throw new _errors_js__rspack_import_1.EH('searchThreads', 'adapter does not implement search'); + } + return adapter.searchThreads({ + query: input.query, + limit: input.limit + }); + }); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } async function readThreadOperation(input) { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ @@ -12604,10 +12972,11 @@ var __webpack_modules__ = { } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); if (Array.isArray(result.threads)) { - return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; + const via = result.query ? ` matching ${JSON.stringify(result.query)}` : ''; + return `${result.threads.length} threads${via} via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { - const mode = result.full ? 'full' : 'visible'; + const mode = result.full ? 'full' : 'page'; return `${result.turns.length} turns (${mode}) on ${result.threadId} via ${result.backend ?? 'unknown'}`; } if (result.delivery === 'accepted') { @@ -12625,7 +12994,8 @@ var __webpack_modules__ = { UK: ()=>readThreadOperation, UP: ()=>sendOperation, Uj: ()=>statusOperation, - tJ: ()=>listThreadsOperation + tJ: ()=>listThreadsOperation, + zg: ()=>searchThreadsOperation }, { FD: resultSchema }); @@ -12633,6 +13003,7 @@ var __webpack_modules__ = { "./src/core/chatgpt-desktop/thread-ids.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _cdp_dom_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); const LOCAL_THREAD_ID_PREFIX = 'local:'; + const HISTORY_CONTENT_TURN_PREFIX = 'history-content:turn:'; function isTemporaryDesktopThreadId(threadId) { return threadId.startsWith(_cdp_dom_js__rspack_import_0.hA); } @@ -12644,6 +13015,13 @@ var __webpack_modules__ = { } return threadId; } + function requireAppServerThreadId(threadId) { + const bare = toAppServerThreadId(threadId); + if (!bare) { + throw new Error(`No app-server thread id mapping for ${JSON.stringify(threadId)} ` + `(temporary Desktop rows need CDP; strip a leading "local:" for durable ids)`); + } + return bare; + } function toDesktopThreadId(threadId) { if (!threadId || isTemporaryDesktopThreadId(threadId)) return threadId; if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) return threadId; @@ -12654,22 +13032,22 @@ var __webpack_modules__ = { const right = toAppServerThreadId(b) ?? b; return left === right; } + function toDomTurnKey(turnId) { + if (!turnId) return turnId; + if (turnId.startsWith(HISTORY_CONTENT_TURN_PREFIX)) return turnId; + return `${HISTORY_CONTENT_TURN_PREFIX}${turnId}`; + } function appServerThreadIdCandidates(threadId) { - if (!threadId || isTemporaryDesktopThreadId(threadId)) return []; const bare = toAppServerThreadId(threadId); - const out = []; - const push = (id)=>{ - if (id && !out.includes(id)) out.push(id); - }; - push(bare); - push(threadId); - if (bare) push(toDesktopThreadId(bare)); - return out; + return bare ? [ + bare + ] : []; } __webpack_require__.d(__webpack_exports__, { BS: ()=>toDesktopThreadId, - EJ: ()=>appServerThreadIdCandidates, LV: ()=>threadIdsEquivalent, + NM: ()=>requireAppServerThreadId, + Sr: ()=>toDomTurnKey, nn: ()=>toAppServerThreadId, vr: ()=>isTemporaryDesktopThreadId }); @@ -24403,6 +24781,13 @@ var __webpack_modules__ = { if (value == null) return null; return typeof value === "string" ? singleLine(value) : value; } + function summarizeSection(section) { + if (!isObject(section) || typeof section.id !== "string" || !section.id) return null; + return { + id: singleLine(section.id), + name: lineField(section.name) + }; + } function summarizeThread(t) { if (!isObject(t) || typeof t.id !== "string" || !t.id) throw new CodexProtocolError("thread/list", "entry without a string `id`"); const type = isObject(t.status) && typeof t.status.type === "string" ? t.status.type : "unknown"; @@ -24414,7 +24799,13 @@ var __webpack_modules__ = { preview: typeof t.preview === "string" ? stripTerminalControls(t.preview) : "", cwd: lineField(t.cwd), source: sourceField(t.source), - updatedAt: typeof t.updatedAt === "number" ? t.updatedAt : null + createdAt: typeof t.createdAt === "number" ? t.createdAt : null, + updatedAt: typeof t.updatedAt === "number" ? t.updatedAt : null, + section: summarizeSection(t.section), + projectId: lineField(t.projectId), + modelProvider: lineField(t.modelProvider), + model: lineField(t.model), + originator: lineField(t.originator) }; } const THREAD_LIST_MAX_LIMIT = 200; @@ -24428,6 +24819,7 @@ var __webpack_modules__ = { const params = { limit, useStateDbOnly: true, + modelProviders: [], ...cursor !== undefined ? { cursor } : {} @@ -27715,9 +28107,9 @@ function __webpack_require__(moduleId) { var __webpack_exports__ = {}; var node_worker_threads__rspack_import_0 = __webpack_require__("node:worker_threads"); var react__rspack_import_1 = __webpack_require__("./node_modules/react/react.react-server.js"); -var _agent_bundle_runtime_flight_server__rspack_import_45 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); -var _agent_bundle_runtime__rspack_import_43 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); -var _agent_bundle_runtime__rspack_import_44 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); +var _agent_bundle_runtime_flight_server__rspack_import_46 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); +var _agent_bundle_runtime__rspack_import_44 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); +var _agent_bundle_runtime__rspack_import_45 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); var node_url__rspack_import_2 = __webpack_require__("node:url"); var _src_cli_approvals_list_tsx__rspack_import_3 = __webpack_require__("./src/cli/approvals/list.tsx"); var _src_cli_approvals_respond_tsx__rspack_import_4 = __webpack_require__("./src/cli/approvals/respond.tsx"); @@ -27727,38 +28119,39 @@ var _src_cli_bots_get_tsx__rspack_import_7 = __webpack_require__("./src/cli/bots var _src_cli_bots_list_tsx__rspack_import_8 = __webpack_require__("./src/cli/bots/list.tsx"); var _src_cli_bots_update_tsx__rspack_import_9 = __webpack_require__("./src/cli/bots/update.tsx"); var _src_cli_chatgpt_desktop_read_tsx__rspack_import_10 = __webpack_require__("./src/cli/chatgpt-desktop/read.tsx"); -var _src_cli_chatgpt_desktop_send_tsx__rspack_import_11 = __webpack_require__("./src/cli/chatgpt-desktop/send.tsx"); -var _src_cli_chatgpt_desktop_status_tsx__rspack_import_12 = __webpack_require__("./src/cli/chatgpt-desktop/status.tsx"); -var _src_cli_chatgpt_desktop_threads_tsx__rspack_import_13 = __webpack_require__("./src/cli/chatgpt-desktop/threads.tsx"); -var _src_cli_claude_send_tsx__rspack_import_14 = __webpack_require__("./src/cli/claude/send.tsx"); -var _src_cli_codex_bridge_respond_tsx__rspack_import_15 = __webpack_require__("./src/cli/codex/bridge/respond.tsx"); -var _src_cli_codex_bridge_run_tsx__rspack_import_16 = __webpack_require__("./src/cli/codex/bridge/run.tsx"); -var _src_cli_codex_bridge_start_tsx__rspack_import_17 = __webpack_require__("./src/cli/codex/bridge/start.tsx"); -var _src_cli_codex_bridge_status_tsx__rspack_import_18 = __webpack_require__("./src/cli/codex/bridge/status.tsx"); -var _src_cli_codex_bridge_stop_tsx__rspack_import_19 = __webpack_require__("./src/cli/codex/bridge/stop.tsx"); -var _src_cli_codex_desktop_shim_tsx__rspack_import_20 = __webpack_require__("./src/cli/codex/desktop-shim.tsx"); -var _src_cli_codex_list_threads_tsx__rspack_import_21 = __webpack_require__("./src/cli/codex/list-threads.tsx"); -var _src_cli_codex_queue_tsx__rspack_import_22 = __webpack_require__("./src/cli/codex/queue.tsx"); -var _src_cli_codex_send_tsx__rspack_import_23 = __webpack_require__("./src/cli/codex/send.tsx"); -var _src_cli_codex_status_tsx__rspack_import_24 = __webpack_require__("./src/cli/codex/status.tsx"); -var _src_cli_codex_wait_tsx__rspack_import_25 = __webpack_require__("./src/cli/codex/wait.tsx"); -var _src_cli_codex_watch_tsx__rspack_import_26 = __webpack_require__("./src/cli/codex/watch.tsx"); -var _src_cli_doctor_tsx__rspack_import_27 = __webpack_require__("./src/cli/doctor.tsx"); -var _src_cli_groups_add_tsx__rspack_import_28 = __webpack_require__("./src/cli/groups/add.tsx"); -var _src_cli_groups_create_tsx__rspack_import_29 = __webpack_require__("./src/cli/groups/create.tsx"); -var _src_cli_groups_delete_tsx__rspack_import_30 = __webpack_require__("./src/cli/groups/delete.tsx"); -var _src_cli_groups_get_tsx__rspack_import_31 = __webpack_require__("./src/cli/groups/get.tsx"); -var _src_cli_groups_list_tsx__rspack_import_32 = __webpack_require__("./src/cli/groups/list.tsx"); -var _src_cli_groups_members_tsx__rspack_import_33 = __webpack_require__("./src/cli/groups/members.tsx"); -var _src_cli_groups_remove_tsx__rspack_import_34 = __webpack_require__("./src/cli/groups/remove.tsx"); -var _src_cli_groups_set_tsx__rspack_import_35 = __webpack_require__("./src/cli/groups/set.tsx"); -var _src_cli_groups_update_tsx__rspack_import_36 = __webpack_require__("./src/cli/groups/update.tsx"); -var _src_cli_history_tsx__rspack_import_37 = __webpack_require__("./src/cli/history.tsx"); -var _src_cli_send_tsx__rspack_import_38 = __webpack_require__("./src/cli/send.tsx"); -var _src_cli_skills_add_tsx__rspack_import_39 = __webpack_require__("./src/cli/skills/add.tsx"); -var _src_cli_skills_list_tsx__rspack_import_40 = __webpack_require__("./src/cli/skills/list.tsx"); -var _src_cli_skills_remove_tsx__rspack_import_41 = __webpack_require__("./src/cli/skills/remove.tsx"); -var _src_cli_thread_tsx__rspack_import_42 = __webpack_require__("./src/cli/thread.tsx"); +var _src_cli_chatgpt_desktop_search_tsx__rspack_import_11 = __webpack_require__("./src/cli/chatgpt-desktop/search.tsx"); +var _src_cli_chatgpt_desktop_send_tsx__rspack_import_12 = __webpack_require__("./src/cli/chatgpt-desktop/send.tsx"); +var _src_cli_chatgpt_desktop_status_tsx__rspack_import_13 = __webpack_require__("./src/cli/chatgpt-desktop/status.tsx"); +var _src_cli_chatgpt_desktop_threads_tsx__rspack_import_14 = __webpack_require__("./src/cli/chatgpt-desktop/threads.tsx"); +var _src_cli_claude_send_tsx__rspack_import_15 = __webpack_require__("./src/cli/claude/send.tsx"); +var _src_cli_codex_bridge_respond_tsx__rspack_import_16 = __webpack_require__("./src/cli/codex/bridge/respond.tsx"); +var _src_cli_codex_bridge_run_tsx__rspack_import_17 = __webpack_require__("./src/cli/codex/bridge/run.tsx"); +var _src_cli_codex_bridge_start_tsx__rspack_import_18 = __webpack_require__("./src/cli/codex/bridge/start.tsx"); +var _src_cli_codex_bridge_status_tsx__rspack_import_19 = __webpack_require__("./src/cli/codex/bridge/status.tsx"); +var _src_cli_codex_bridge_stop_tsx__rspack_import_20 = __webpack_require__("./src/cli/codex/bridge/stop.tsx"); +var _src_cli_codex_desktop_shim_tsx__rspack_import_21 = __webpack_require__("./src/cli/codex/desktop-shim.tsx"); +var _src_cli_codex_list_threads_tsx__rspack_import_22 = __webpack_require__("./src/cli/codex/list-threads.tsx"); +var _src_cli_codex_queue_tsx__rspack_import_23 = __webpack_require__("./src/cli/codex/queue.tsx"); +var _src_cli_codex_send_tsx__rspack_import_24 = __webpack_require__("./src/cli/codex/send.tsx"); +var _src_cli_codex_status_tsx__rspack_import_25 = __webpack_require__("./src/cli/codex/status.tsx"); +var _src_cli_codex_wait_tsx__rspack_import_26 = __webpack_require__("./src/cli/codex/wait.tsx"); +var _src_cli_codex_watch_tsx__rspack_import_27 = __webpack_require__("./src/cli/codex/watch.tsx"); +var _src_cli_doctor_tsx__rspack_import_28 = __webpack_require__("./src/cli/doctor.tsx"); +var _src_cli_groups_add_tsx__rspack_import_29 = __webpack_require__("./src/cli/groups/add.tsx"); +var _src_cli_groups_create_tsx__rspack_import_30 = __webpack_require__("./src/cli/groups/create.tsx"); +var _src_cli_groups_delete_tsx__rspack_import_31 = __webpack_require__("./src/cli/groups/delete.tsx"); +var _src_cli_groups_get_tsx__rspack_import_32 = __webpack_require__("./src/cli/groups/get.tsx"); +var _src_cli_groups_list_tsx__rspack_import_33 = __webpack_require__("./src/cli/groups/list.tsx"); +var _src_cli_groups_members_tsx__rspack_import_34 = __webpack_require__("./src/cli/groups/members.tsx"); +var _src_cli_groups_remove_tsx__rspack_import_35 = __webpack_require__("./src/cli/groups/remove.tsx"); +var _src_cli_groups_set_tsx__rspack_import_36 = __webpack_require__("./src/cli/groups/set.tsx"); +var _src_cli_groups_update_tsx__rspack_import_37 = __webpack_require__("./src/cli/groups/update.tsx"); +var _src_cli_history_tsx__rspack_import_38 = __webpack_require__("./src/cli/history.tsx"); +var _src_cli_send_tsx__rspack_import_39 = __webpack_require__("./src/cli/send.tsx"); +var _src_cli_skills_add_tsx__rspack_import_40 = __webpack_require__("./src/cli/skills/add.tsx"); +var _src_cli_skills_list_tsx__rspack_import_41 = __webpack_require__("./src/cli/skills/list.tsx"); +var _src_cli_skills_remove_tsx__rspack_import_42 = __webpack_require__("./src/cli/skills/remove.tsx"); +var _src_cli_thread_tsx__rspack_import_43 = __webpack_require__("./src/cli/thread.tsx"); const route0 = Object.assign({}, Reflect.get(_src_cli_approvals_list_tsx__rspack_import_3, 'default'), _src_cli_approvals_list_tsx__rspack_import_3); const route1 = Object.assign({}, Reflect.get(_src_cli_approvals_respond_tsx__rspack_import_4, 'default'), _src_cli_approvals_respond_tsx__rspack_import_4); const route2 = Object.assign({}, Reflect.get(_src_cli_bots_create_tsx__rspack_import_5, 'default'), _src_cli_bots_create_tsx__rspack_import_5); @@ -27767,39 +28160,40 @@ const route4 = Object.assign({}, Reflect.get(_src_cli_bots_get_tsx__rspack_impor const route5 = Object.assign({}, Reflect.get(_src_cli_bots_list_tsx__rspack_import_8, 'default'), _src_cli_bots_list_tsx__rspack_import_8); const route6 = Object.assign({}, Reflect.get(_src_cli_bots_update_tsx__rspack_import_9, 'default'), _src_cli_bots_update_tsx__rspack_import_9); const route7 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_read_tsx__rspack_import_10, 'default'), _src_cli_chatgpt_desktop_read_tsx__rspack_import_10); -const route8 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_send_tsx__rspack_import_11, 'default'), _src_cli_chatgpt_desktop_send_tsx__rspack_import_11); -const route9 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_status_tsx__rspack_import_12, 'default'), _src_cli_chatgpt_desktop_status_tsx__rspack_import_12); -const route10 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_threads_tsx__rspack_import_13, 'default'), _src_cli_chatgpt_desktop_threads_tsx__rspack_import_13); -const route11 = Object.assign({}, Reflect.get(_src_cli_claude_send_tsx__rspack_import_14, 'default'), _src_cli_claude_send_tsx__rspack_import_14); -const route12 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_respond_tsx__rspack_import_15, 'default'), _src_cli_codex_bridge_respond_tsx__rspack_import_15); -const route13 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_run_tsx__rspack_import_16, 'default'), _src_cli_codex_bridge_run_tsx__rspack_import_16); -const route14 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_start_tsx__rspack_import_17, 'default'), _src_cli_codex_bridge_start_tsx__rspack_import_17); -const route15 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_status_tsx__rspack_import_18, 'default'), _src_cli_codex_bridge_status_tsx__rspack_import_18); -const route16 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_stop_tsx__rspack_import_19, 'default'), _src_cli_codex_bridge_stop_tsx__rspack_import_19); -const route17 = Object.assign({}, Reflect.get(_src_cli_codex_desktop_shim_tsx__rspack_import_20, 'default'), _src_cli_codex_desktop_shim_tsx__rspack_import_20); -const route18 = Object.assign({}, Reflect.get(_src_cli_codex_list_threads_tsx__rspack_import_21, 'default'), _src_cli_codex_list_threads_tsx__rspack_import_21); -const route19 = Object.assign({}, Reflect.get(_src_cli_codex_queue_tsx__rspack_import_22, 'default'), _src_cli_codex_queue_tsx__rspack_import_22); -const route20 = Object.assign({}, Reflect.get(_src_cli_codex_send_tsx__rspack_import_23, 'default'), _src_cli_codex_send_tsx__rspack_import_23); -const route21 = Object.assign({}, Reflect.get(_src_cli_codex_status_tsx__rspack_import_24, 'default'), _src_cli_codex_status_tsx__rspack_import_24); -const route22 = Object.assign({}, Reflect.get(_src_cli_codex_wait_tsx__rspack_import_25, 'default'), _src_cli_codex_wait_tsx__rspack_import_25); -const route23 = Object.assign({}, Reflect.get(_src_cli_codex_watch_tsx__rspack_import_26, 'default'), _src_cli_codex_watch_tsx__rspack_import_26); -const route24 = Object.assign({}, Reflect.get(_src_cli_doctor_tsx__rspack_import_27, 'default'), _src_cli_doctor_tsx__rspack_import_27); -const route25 = Object.assign({}, Reflect.get(_src_cli_groups_add_tsx__rspack_import_28, 'default'), _src_cli_groups_add_tsx__rspack_import_28); -const route26 = Object.assign({}, Reflect.get(_src_cli_groups_create_tsx__rspack_import_29, 'default'), _src_cli_groups_create_tsx__rspack_import_29); -const route27 = Object.assign({}, Reflect.get(_src_cli_groups_delete_tsx__rspack_import_30, 'default'), _src_cli_groups_delete_tsx__rspack_import_30); -const route28 = Object.assign({}, Reflect.get(_src_cli_groups_get_tsx__rspack_import_31, 'default'), _src_cli_groups_get_tsx__rspack_import_31); -const route29 = Object.assign({}, Reflect.get(_src_cli_groups_list_tsx__rspack_import_32, 'default'), _src_cli_groups_list_tsx__rspack_import_32); -const route30 = Object.assign({}, Reflect.get(_src_cli_groups_members_tsx__rspack_import_33, 'default'), _src_cli_groups_members_tsx__rspack_import_33); -const route31 = Object.assign({}, Reflect.get(_src_cli_groups_remove_tsx__rspack_import_34, 'default'), _src_cli_groups_remove_tsx__rspack_import_34); -const route32 = Object.assign({}, Reflect.get(_src_cli_groups_set_tsx__rspack_import_35, 'default'), _src_cli_groups_set_tsx__rspack_import_35); -const route33 = Object.assign({}, Reflect.get(_src_cli_groups_update_tsx__rspack_import_36, 'default'), _src_cli_groups_update_tsx__rspack_import_36); -const route34 = Object.assign({}, Reflect.get(_src_cli_history_tsx__rspack_import_37, 'default'), _src_cli_history_tsx__rspack_import_37); -const route35 = Object.assign({}, Reflect.get(_src_cli_send_tsx__rspack_import_38, 'default'), _src_cli_send_tsx__rspack_import_38); -const route36 = Object.assign({}, Reflect.get(_src_cli_skills_add_tsx__rspack_import_39, 'default'), _src_cli_skills_add_tsx__rspack_import_39); -const route37 = Object.assign({}, Reflect.get(_src_cli_skills_list_tsx__rspack_import_40, 'default'), _src_cli_skills_list_tsx__rspack_import_40); -const route38 = Object.assign({}, Reflect.get(_src_cli_skills_remove_tsx__rspack_import_41, 'default'), _src_cli_skills_remove_tsx__rspack_import_41); -const route39 = Object.assign({}, Reflect.get(_src_cli_thread_tsx__rspack_import_42, 'default'), _src_cli_thread_tsx__rspack_import_42); -const pluginRoot = (0, _agent_bundle_runtime__rspack_import_43.E7)({ +const route8 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_search_tsx__rspack_import_11, 'default'), _src_cli_chatgpt_desktop_search_tsx__rspack_import_11); +const route9 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_send_tsx__rspack_import_12, 'default'), _src_cli_chatgpt_desktop_send_tsx__rspack_import_12); +const route10 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_status_tsx__rspack_import_13, 'default'), _src_cli_chatgpt_desktop_status_tsx__rspack_import_13); +const route11 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_threads_tsx__rspack_import_14, 'default'), _src_cli_chatgpt_desktop_threads_tsx__rspack_import_14); +const route12 = Object.assign({}, Reflect.get(_src_cli_claude_send_tsx__rspack_import_15, 'default'), _src_cli_claude_send_tsx__rspack_import_15); +const route13 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_respond_tsx__rspack_import_16, 'default'), _src_cli_codex_bridge_respond_tsx__rspack_import_16); +const route14 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_run_tsx__rspack_import_17, 'default'), _src_cli_codex_bridge_run_tsx__rspack_import_17); +const route15 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_start_tsx__rspack_import_18, 'default'), _src_cli_codex_bridge_start_tsx__rspack_import_18); +const route16 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_status_tsx__rspack_import_19, 'default'), _src_cli_codex_bridge_status_tsx__rspack_import_19); +const route17 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_stop_tsx__rspack_import_20, 'default'), _src_cli_codex_bridge_stop_tsx__rspack_import_20); +const route18 = Object.assign({}, Reflect.get(_src_cli_codex_desktop_shim_tsx__rspack_import_21, 'default'), _src_cli_codex_desktop_shim_tsx__rspack_import_21); +const route19 = Object.assign({}, Reflect.get(_src_cli_codex_list_threads_tsx__rspack_import_22, 'default'), _src_cli_codex_list_threads_tsx__rspack_import_22); +const route20 = Object.assign({}, Reflect.get(_src_cli_codex_queue_tsx__rspack_import_23, 'default'), _src_cli_codex_queue_tsx__rspack_import_23); +const route21 = Object.assign({}, Reflect.get(_src_cli_codex_send_tsx__rspack_import_24, 'default'), _src_cli_codex_send_tsx__rspack_import_24); +const route22 = Object.assign({}, Reflect.get(_src_cli_codex_status_tsx__rspack_import_25, 'default'), _src_cli_codex_status_tsx__rspack_import_25); +const route23 = Object.assign({}, Reflect.get(_src_cli_codex_wait_tsx__rspack_import_26, 'default'), _src_cli_codex_wait_tsx__rspack_import_26); +const route24 = Object.assign({}, Reflect.get(_src_cli_codex_watch_tsx__rspack_import_27, 'default'), _src_cli_codex_watch_tsx__rspack_import_27); +const route25 = Object.assign({}, Reflect.get(_src_cli_doctor_tsx__rspack_import_28, 'default'), _src_cli_doctor_tsx__rspack_import_28); +const route26 = Object.assign({}, Reflect.get(_src_cli_groups_add_tsx__rspack_import_29, 'default'), _src_cli_groups_add_tsx__rspack_import_29); +const route27 = Object.assign({}, Reflect.get(_src_cli_groups_create_tsx__rspack_import_30, 'default'), _src_cli_groups_create_tsx__rspack_import_30); +const route28 = Object.assign({}, Reflect.get(_src_cli_groups_delete_tsx__rspack_import_31, 'default'), _src_cli_groups_delete_tsx__rspack_import_31); +const route29 = Object.assign({}, Reflect.get(_src_cli_groups_get_tsx__rspack_import_32, 'default'), _src_cli_groups_get_tsx__rspack_import_32); +const route30 = Object.assign({}, Reflect.get(_src_cli_groups_list_tsx__rspack_import_33, 'default'), _src_cli_groups_list_tsx__rspack_import_33); +const route31 = Object.assign({}, Reflect.get(_src_cli_groups_members_tsx__rspack_import_34, 'default'), _src_cli_groups_members_tsx__rspack_import_34); +const route32 = Object.assign({}, Reflect.get(_src_cli_groups_remove_tsx__rspack_import_35, 'default'), _src_cli_groups_remove_tsx__rspack_import_35); +const route33 = Object.assign({}, Reflect.get(_src_cli_groups_set_tsx__rspack_import_36, 'default'), _src_cli_groups_set_tsx__rspack_import_36); +const route34 = Object.assign({}, Reflect.get(_src_cli_groups_update_tsx__rspack_import_37, 'default'), _src_cli_groups_update_tsx__rspack_import_37); +const route35 = Object.assign({}, Reflect.get(_src_cli_history_tsx__rspack_import_38, 'default'), _src_cli_history_tsx__rspack_import_38); +const route36 = Object.assign({}, Reflect.get(_src_cli_send_tsx__rspack_import_39, 'default'), _src_cli_send_tsx__rspack_import_39); +const route37 = Object.assign({}, Reflect.get(_src_cli_skills_add_tsx__rspack_import_40, 'default'), _src_cli_skills_add_tsx__rspack_import_40); +const route38 = Object.assign({}, Reflect.get(_src_cli_skills_list_tsx__rspack_import_41, 'default'), _src_cli_skills_list_tsx__rspack_import_41); +const route39 = Object.assign({}, Reflect.get(_src_cli_skills_remove_tsx__rspack_import_42, 'default'), _src_cli_skills_remove_tsx__rspack_import_42); +const route40 = Object.assign({}, Reflect.get(_src_cli_thread_tsx__rspack_import_43, 'default'), _src_cli_thread_tsx__rspack_import_43); +const pluginRoot = (0, _agent_bundle_runtime__rspack_import_44.E7)({ fallback: (0, node_url__rspack_import_2.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); @@ -27863,197 +28257,203 @@ const routes = Object.freeze({ name: "chatgpt-desktop read", module: route7 }), + "cli:chatgpt-desktop/search": Object.freeze({ + id: "cli:chatgpt-desktop/search", + kind: "cli", + name: "chatgpt-desktop search", + module: route8 + }), "cli:chatgpt-desktop/send": Object.freeze({ id: "cli:chatgpt-desktop/send", kind: "cli", name: "chatgpt-desktop send", - module: route8 + module: route9 }), "cli:chatgpt-desktop/status": Object.freeze({ id: "cli:chatgpt-desktop/status", kind: "cli", name: "chatgpt-desktop status", - module: route9 + module: route10 }), "cli:chatgpt-desktop/threads": Object.freeze({ id: "cli:chatgpt-desktop/threads", kind: "cli", name: "chatgpt-desktop threads", - module: route10 + module: route11 }), "cli:claude/send": Object.freeze({ id: "cli:claude/send", kind: "cli", name: "claude send", - module: route11 + module: route12 }), "cli:codex/bridge/respond": Object.freeze({ id: "cli:codex/bridge/respond", kind: "cli", name: "codex bridge respond", - module: route12 + module: route13 }), "cli:codex/bridge/run": Object.freeze({ id: "cli:codex/bridge/run", kind: "cli", name: "codex bridge run", - module: route13 + module: route14 }), "cli:codex/bridge/start": Object.freeze({ id: "cli:codex/bridge/start", kind: "cli", name: "codex bridge start", - module: route14 + module: route15 }), "cli:codex/bridge/status": Object.freeze({ id: "cli:codex/bridge/status", kind: "cli", name: "codex bridge status", - module: route15 + module: route16 }), "cli:codex/bridge/stop": Object.freeze({ id: "cli:codex/bridge/stop", kind: "cli", name: "codex bridge stop", - module: route16 + module: route17 }), "cli:codex/desktop-shim": Object.freeze({ id: "cli:codex/desktop-shim", kind: "cli", name: "codex desktop-shim", - module: route17 + module: route18 }), "cli:codex/list-threads": Object.freeze({ id: "cli:codex/list-threads", kind: "cli", name: "codex list-threads", - module: route18 + module: route19 }), "cli:codex/queue": Object.freeze({ id: "cli:codex/queue", kind: "cli", name: "codex queue", - module: route19 + module: route20 }), "cli:codex/send": Object.freeze({ id: "cli:codex/send", kind: "cli", name: "codex send", - module: route20 + module: route21 }), "cli:codex/status": Object.freeze({ id: "cli:codex/status", kind: "cli", name: "codex status", - module: route21 + module: route22 }), "cli:codex/wait": Object.freeze({ id: "cli:codex/wait", kind: "cli", name: "codex wait", - module: route22 + module: route23 }), "cli:codex/watch": Object.freeze({ id: "cli:codex/watch", kind: "cli", name: "codex watch", - module: route23 + module: route24 }), "cli:doctor": Object.freeze({ id: "cli:doctor", kind: "cli", name: "doctor", - module: route24 + module: route25 }), "cli:groups/add": Object.freeze({ id: "cli:groups/add", kind: "cli", name: "groups add", - module: route25 + module: route26 }), "cli:groups/create": Object.freeze({ id: "cli:groups/create", kind: "cli", name: "groups create", - module: route26 + module: route27 }), "cli:groups/delete": Object.freeze({ id: "cli:groups/delete", kind: "cli", name: "groups delete", - module: route27 + module: route28 }), "cli:groups/get": Object.freeze({ id: "cli:groups/get", kind: "cli", name: "groups get", - module: route28 + module: route29 }), "cli:groups/list": Object.freeze({ id: "cli:groups/list", kind: "cli", name: "groups list", - module: route29 + module: route30 }), "cli:groups/members": Object.freeze({ id: "cli:groups/members", kind: "cli", name: "groups members", - module: route30 + module: route31 }), "cli:groups/remove": Object.freeze({ id: "cli:groups/remove", kind: "cli", name: "groups remove", - module: route31 + module: route32 }), "cli:groups/set": Object.freeze({ id: "cli:groups/set", kind: "cli", name: "groups set", - module: route32 + module: route33 }), "cli:groups/update": Object.freeze({ id: "cli:groups/update", kind: "cli", name: "groups update", - module: route33 + module: route34 }), "cli:history": Object.freeze({ id: "cli:history", kind: "cli", name: "history", - module: route34 + module: route35 }), "cli:send": Object.freeze({ id: "cli:send", kind: "cli", name: "send", - module: route35 + module: route36 }), "cli:skills/add": Object.freeze({ id: "cli:skills/add", kind: "cli", name: "skills add", - module: route36 + module: route37 }), "cli:skills/list": Object.freeze({ id: "cli:skills/list", kind: "cli", name: "skills list", - module: route37 + module: route38 }), "cli:skills/remove": Object.freeze({ id: "cli:skills/remove", kind: "cli", name: "skills remove", - module: route38 + module: route39 }), "cli:thread": Object.freeze({ id: "cli:thread", kind: "cli", name: "thread", - module: route39 + module: route40 }) }); const requests = new Map(); @@ -28088,18 +28488,18 @@ const render = async (message)=>{ }; try { const cwd = process.cwd(); - await (0, _agent_bundle_runtime__rspack_import_44.iC)({ + await (0, _agent_bundle_runtime__rspack_import_45.iC)({ capabilities: { - command: (0, _agent_bundle_runtime__rspack_import_44.hU)(), - filesystem: (0, _agent_bundle_runtime__rspack_import_44.hU)(), - network: (0, _agent_bundle_runtime__rspack_import_44.hU)(), - projectRoot: (0, _agent_bundle_runtime__rspack_import_44.qC)({ + command: (0, _agent_bundle_runtime__rspack_import_45.hU)(), + filesystem: (0, _agent_bundle_runtime__rspack_import_45.hU)(), + network: (0, _agent_bundle_runtime__rspack_import_45.hU)(), + projectRoot: (0, _agent_bundle_runtime__rspack_import_45.qC)({ root: cwd }, 'derived') }, - host: (0, _agent_bundle_runtime__rspack_import_44.hU)('unsupported-surface'), + host: (0, _agent_bundle_runtime__rspack_import_45.hU)('unsupported-surface'), invocation: message.request, - lineage: (0, _agent_bundle_runtime__rspack_import_44.hU)('unsupported-surface'), + lineage: (0, _agent_bundle_runtime__rspack_import_45.hU)('unsupported-surface'), plugin: pluginRoot.identity, progress: { report: async (update)=>{ @@ -28112,8 +28512,8 @@ const render = async (message)=>{ }, process: processHit, signal: controller.signal, - terminal: message.terminal === undefined ? (0, _agent_bundle_runtime__rspack_import_44.hU)('not-provided') : (0, _agent_bundle_runtime__rspack_import_44.qC)(message.terminal, 'native'), - workspace: (0, _agent_bundle_runtime__rspack_import_44.qC)({ + terminal: message.terminal === undefined ? (0, _agent_bundle_runtime__rspack_import_45.hU)('not-provided') : (0, _agent_bundle_runtime__rspack_import_45.qC)(message.terminal, 'native'), + workspace: (0, _agent_bundle_runtime__rspack_import_45.qC)({ root: cwd }, 'derived') }, async ()=>{ @@ -28122,7 +28522,7 @@ const render = async (message)=>{ type: 'observed-render-start' }); const renderStartedAt = performance.now(); - const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_45.y)(composeLayouts(observedRoute, { + const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_46.y)(composeLayouts(observedRoute, { ...message.props, signal: controller.signal }, controller.signal), { diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index e262de1..5433b03 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -7024,7 +7024,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Read a ChatGPT Desktop thread. Visible turns via CDP; --full / deep history via app-server (wheel crawl last-resort).', + description: 'Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.', exitCode: 'result', positionals: [ 'threadId' @@ -7093,6 +7093,62 @@ var __webpack_modules__ = { inputSchema: inputSchema }); }, + "./src/cli/chatgpt-desktop/search.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const config = { + description: 'Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.', + exitCode: 'result', + positionals: [ + 'query' + ], + inputJsonSchema: { + additionalProperties: false, + properties: { + limit: { + default: 50, + description: 'Max matches (1-200)', + type: 'number' + }, + port: { + description: 'Local CDP port', + type: 'number' + }, + query: { + type: 'string' + } + }, + required: [ + 'query' + ], + type: 'object' + } + }; + const inputSchema = zod__rspack_import_2.Ikc({ + limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), + port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), + query: zod__rspack_import_2.YjP().min(1).max(512) + }).strict(); + async function chatgptDesktopSearch({ input }) { + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.zg)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out) + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>chatgptDesktopSearch, + resultSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_1.FD + }, { + config: config, + inputSchema: inputSchema + }); + }, "./src/cli/chatgpt-desktop/send.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); @@ -9538,79 +9594,74 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/app-server-fallback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); - var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); - async function appServerListThreads({ limit = 50 } = {}) { + var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _remote_threads_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + async function appServerListThreads({ limit = 50, cursor } = {}) { const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit + limit, + cursor }); return { backend: 'app-server', limit: out.limit, - threads: out.threads.map((thread)=>{ - const bare = String(thread.id ?? ''); - return { - threadId: bare ? (0, _thread_ids_js__rspack_import_1.BS)(bare) : '', - title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), - pinned: false, - selected: false, - kind: 'codex' - }; - }) + nextCursor: out.nextCursor ?? null, + threads: out.threads.map(mapListedThread) }; } - async function appServerReadThread({ threadId, limit = 100, full = false }) { - const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); - if (candidates.length === 0) { - throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); + async function appServerSearchThreads({ query, limit = 50 }) { + const needle = query.trim().toLowerCase(); + if (!needle) { + return appServerListThreads({ + limit + }); } - const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); - try { - let lastError; - for (const candidate of candidates){ - try { - const turns = await readTurnsForId(client, candidate, { - limit, - full - }); - return { - threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), - turns, - backend: 'app-server', - limit, - full - }; - } catch (error) { - lastError = error; - } + const matched = []; + let cursor; + for(let page = 0; page < 20 && matched.length < limit; page++){ + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit: 200, + cursor + }); + for (const thread of out.threads){ + const mapped = mapListedThread(thread); + if (threadMatchesQuery(mapped, needle)) matched.push(mapped); + if (matched.length >= limit) break; } - throw lastError instanceof Error ? lastError : new Error(`app-server thread read failed for ${threadId}`); - } finally{ - client.close(); + if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + cursor = out.nextCursor; } + return { + backend: 'app-server', + limit, + query, + nextCursor: null, + threads: matched.slice(0, limit) + }; } - async function appServerOpenThread(threadId) { - const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); - if (candidates.length === 0) { - throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); - } + async function appServerReadThread({ threadId, limit = 100, full = false }) { + const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { - let lastError; - for (const candidate of candidates){ - try { - await client.request('thread/resume', { - threadId: candidate, - excludeTurns: true - }); - return { - threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), - backend: 'app-server' - }; - } catch (error) { - lastError = error; - } - } - throw lastError instanceof Error ? lastError : new Error(`app-server thread/resume failed for ${threadId}`); + const meta = await readThreadMetadata(client, bare); + const turns = await listTurnsFull(client, bare, { + limit, + full + }); + return { + threadId: (0, _thread_ids_js__rspack_import_3.BS)(bare), + turns, + backend: 'app-server', + limit, + full, + title: meta.title, + cwd: meta.cwd, + status: meta.status, + modelProvider: meta.modelProvider, + model: meta.model + }; + } catch (error) { + throw maybeRemoteThreadError(error, bare); } finally{ client.close(); } @@ -9623,32 +9674,110 @@ var __webpack_modules__ = { socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined }; } - async function readTurnsForId(client, threadId, { limit, full }) { + function mapListedThread(thread) { + const bare = String(thread.id ?? ''); + const section = thread.section && typeof thread.section.id === 'string' ? { + id: thread.section.id, + name: thread.section.name ?? null + } : null; + const pinned = section?.id === 'Pinned' || section?.name === 'Pinned' || false; + return { + threadId: bare ? (0, _thread_ids_js__rspack_import_3.BS)(bare) : '', + title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), + pinned, + selected: false, + kind: 'codex', + preview: typeof thread.preview === 'string' ? thread.preview : undefined, + cwd: thread.cwd ?? null, + createdAt: thread.createdAt ?? null, + updatedAt: thread.updatedAt ?? null, + section, + projectId: thread.projectId ?? null, + project: thread.projectId ?? undefined, + status: thread.status, + modelProvider: thread.modelProvider ?? null, + model: thread.model ?? null, + originator: thread.originator ?? null + }; + } + function threadMatchesQuery(thread, needle) { + const haystacks = [ + thread.threadId, + thread.title, + thread.preview, + thread.cwd, + thread.project, + thread.projectId, + thread.model, + thread.modelProvider, + thread.originator, + thread.section?.name, + thread.section?.id + ]; + return haystacks.some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } + async function readThreadMetadata(client, threadId) { try { const read = await client.request('thread/read', { threadId }); - const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - if (Array.isArray(raw) && raw.length > 0) { - return sliceTurns(normalizeTurns(raw), { - limit, - full + const thread = read.thread && typeof read.thread === 'object' ? read.thread : {}; + const statusObj = thread.status; + const statusType = statusObj && typeof statusObj === 'object' && typeof statusObj.type === 'string' ? String(statusObj.type) : typeof thread.status === 'string' ? thread.status : undefined; + return { + title: typeof thread.name === 'string' ? thread.name : typeof thread.preview === 'string' ? thread.preview : undefined, + cwd: typeof thread.cwd === 'string' ? thread.cwd : null, + status: statusType, + modelProvider: typeof thread.modelProvider === 'string' ? thread.modelProvider : null, + model: typeof thread.model === 'string' ? thread.model : null + }; + } catch (error) { + throw maybeRemoteThreadError(error, threadId); + } + } + async function listTurnsFull(client, threadId, { limit, full }) { + const collected = []; + let cursor; + try { + for(let page = 0; page < 40; page++){ + const result = await client.request('thread/turns/list', { + threadId, + limit: 100, + itemsView: 'full', + ...cursor ? { + cursor + } : {} }); + if (!Array.isArray(result.data)) { + throw new Error(`thread/turns/list missing data array for ${threadId}`); + } + collected.push(...result.data); + if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; + cursor = result.nextCursor; + if (!full && collected.length >= limit) break; } - } catch {} - try { - const resumed = await client.request('thread/resume', { - threadId, - excludeTurns: false - }); - const raw = resumed.thread?.turns ?? resumed.turns ?? resumed.thread?.items ?? []; - if (Array.isArray(raw) && raw.length > 0) { - return sliceTurns(normalizeTurns(raw), { + } catch (error) { + if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + if (collected.length === 0) { + return listTurnsFallback(client, threadId, { limit, full }); } - } catch {} + throw error; + } + if (collected.length === 0) { + return listTurnsFallback(client, threadId, { + limit, + full + }); + } + return sliceTurns(normalizeTurns(collected), { + limit, + full + }); + } + async function listTurnsFallback(client, threadId, { limit, full }) { for (const method of [ 'thread/turns/list', 'thread/items/list' @@ -9656,14 +9785,16 @@ var __webpack_modules__ = { try { const collected = []; let cursor; - for(let page = 0; page < 20; page++){ - const result = await client.request(method, { + for(let page = 0; page < 40; page++){ + const params = { threadId, limit: 100, ...cursor ? { cursor } : {} - }); + }; + if (method === 'thread/turns/list') params.itemsView = 'full'; + const result = await client.request(method, params); if (!Array.isArray(result.data)) break; collected.push(...result.data); if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; @@ -9676,7 +9807,9 @@ var __webpack_modules__ = { full }); } - } catch {} + } catch (error) { + if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + } } throw new Error(`app-server has no turn history for thread ${threadId}`); } @@ -9690,24 +9823,116 @@ var __webpack_modules__ = { for (const [index, item] of raw.entries()){ if (!item || typeof item !== 'object') continue; const row = item; - const text = typeof row.text === 'string' ? row.text : typeof row.content === 'string' ? row.content : ''; - const type = String(row.type ?? row.role ?? ''); - let role = 'assistant'; - if (/user/i.test(type)) role = 'user'; - else if (/status|system|reasoning/i.test(type) && !text) role = 'status'; - turns.push({ - turnKey: String(row.id ?? row.turnId ?? index), - role, - text - }); + const id = String(row.id ?? row.turnId ?? index); + const items = Array.isArray(row.items) ? row.items : null; + if (items) { + turns.push(normalizeTurnWithItems(id, row, items)); + continue; + } + turns.push(normalizeLeafItem(id, row)); } return turns; } + function normalizeTurnWithItems(id, row, items) { + let userText = ''; + let assistantText = ''; + let toolText = ''; + let reasoningText = ''; + for (const entry of items){ + if (!entry || typeof entry !== 'object') continue; + const item = entry; + const type = String(item.type ?? item.role ?? ''); + const text = extractText(item); + if (/user/i.test(type)) userText = joinText(userText, text); + else if (/agent|assistant|message/i.test(type) && !/reasoning|tool/i.test(type)) { + assistantText = joinText(assistantText, text); + } else if (/tool/i.test(type)) toolText = joinText(toolText, text || type); + else if (/reasoning/i.test(type)) reasoningText = joinText(reasoningText, text); + } + let role = 'assistant'; + let text = assistantText || userText; + if (userText && !assistantText) { + role = 'user'; + text = userText; + } else if (!userText && !assistantText && toolText) { + role = 'tool'; + text = toolText; + } else if (!userText && !assistantText && reasoningText) { + role = 'reasoning'; + text = reasoningText; + } + return { + turnKey: (0, _thread_ids_js__rspack_import_3.Sr)(id), + role, + text, + ...userText ? { + userText + } : {}, + ...assistantText ? { + assistantText + } : {}, + startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, + endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + }; + } + function normalizeLeafItem(id, row) { + const text = extractText(row); + const type = String(row.type ?? row.role ?? ''); + let role = 'assistant'; + if (/user/i.test(type)) role = 'user'; + else if (/tool/i.test(type)) role = 'tool'; + else if (/reasoning/i.test(type)) role = 'reasoning'; + else if (/status|system/i.test(type) && !text) role = 'status'; + return { + turnKey: (0, _thread_ids_js__rspack_import_3.Sr)(id), + role, + text, + startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, + endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + }; + } + function extractText(row) { + if (typeof row.text === 'string') return row.text; + if (typeof row.content === 'string') return row.content; + if (typeof row.preview === 'string') return row.preview; + return ''; + } + function joinText(left, right) { + if (!right) return left; + if (!left) return right; + return `${left}\n${right}`; + } + function isThreadNotLoaded(error) { + const message = errorMessage(error); + return /thread not loaded|not loaded|invalid thread id/i.test(message); + } + function maybeRemoteThreadError(error, threadId) { + const message = errorMessage(error); + if (/thread not loaded|not loaded/i.test(message)) { + const hostId = (0, _remote_threads_js__rspack_import_2.X)(threadId); + return new _errors_js__rspack_import_1.Rg(threadId, hostId); + } + if (error instanceof Error) return error; + return new Error(message || `app-server error for thread ${threadId}`); + } + function errorMessage(error) { + if (!error) return ''; + if (typeof error === 'string') return error; + if (error instanceof Error) return error.message; + if (typeof error === 'object' && error && 'message' in error) { + return String(error.message); + } + if (typeof error === 'object' && error && 'rpc' in error) { + const rpc = error.rpc; + if (rpc && typeof rpc.message === 'string') return rpc.message; + } + return String(error); + } __webpack_require__.d(__webpack_exports__, { Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, - dM: ()=>appServerStatusProbe, - zu: ()=>appServerOpenThread + aI: ()=>appServerSearchThreads, + dM: ()=>appServerStatusProbe }); }, "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -10579,8 +10804,23 @@ var __webpack_modules__ = { this.name = 'CdpUnreachableError'; } } + class RemoteThreadNotLoadedError extends Error { + code = 'REMOTE_THREAD_NOT_LOADED'; + delivery = 'rejected'; + reason = 'remote-thread-not-loaded'; + threadId; + hostId; + constructor(threadId, hostId = null){ + const owner = hostId ? `owned by remote-control host ${JSON.stringify(hostId)}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ` + `${owner}. SSH remoting is not implemented in this adapter yet.`); + this.name = 'RemoteThreadNotLoadedError'; + this.threadId = threadId; + this.hostId = hostId; + } + } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, + Rg: ()=>RemoteThreadNotLoadedError, c$: ()=>CdpHostRejectedError, sO: ()=>CdpUnreachableError }); @@ -10593,8 +10833,8 @@ var __webpack_modules__ = { var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, + searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, - openThread: _app_server_fallback_js__rspack_import_1.zu, statusProbe: _app_server_fallback_js__rspack_import_1.dM }; class ChatGptDesktopFacade { @@ -10652,30 +10892,45 @@ var __webpack_modules__ = { if (appError) throw appError; throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); } + async searchThreads(options) { + try { + const appList = await this.#fallbacks.searchThreads(options); + const cdpList = await this.#tryCdpList({ + limit: options.limit + }); + if (cdpList) return mergeThreadLists(appList, cdpList); + return appList; + } catch (appError) { + const cdpList = await this.#tryCdpList({ + limit: options.limit + }); + if (!cdpList) throw appError; + const needle = options.query.trim().toLowerCase(); + return { + ...cdpList, + query: options.query, + threads: cdpList.threads.filter((thread)=>{ + if (!needle) return true; + return [ + thread.title, + thread.threadId, + thread.project + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + }) + }; + } + } async readThread(options) { const limit = options.limit ?? 100; const full = options.full ?? false; - const cdpConnected = await this.#tryEnsureCdp(); if ((0, _thread_ids_js__rspack_import_4.vr)(options.threadId)) { - if (!cdpConnected) { - throw new _errors_js__rspack_import_2.sO(`ChatGPT Desktop temporary thread ${options.threadId} requires CDP`); - } + await this.#ensureCdp(); return this.#cdp.readThread({ ...options, limit, full }); } - if (cdpConnected && !full) { - const visible = await this.#cdp.readThread({ - ...options, - limit, - full: false - }); - if (limit <= visible.turns.length) { - return visible; - } - } try { return await this.#fallbacks.readThread({ threadId: options.threadId, @@ -10683,14 +10938,13 @@ var __webpack_modules__ = { full }); } catch (appError) { - if (cdpConnected) { - return this.#cdp.readThread({ - ...options, - limit, - full: true - }); - } - throw appError; + const cdpConnected = await this.#tryEnsureCdp(); + if (!cdpConnected) throw appError; + return this.#cdp.readThread({ + ...options, + limit, + full: full || true + }); } } async sendMessage(options) { @@ -10702,13 +10956,8 @@ var __webpack_modules__ = { return this.#cdp.waitForReply(options); } async openThread(threadId, options) { - try { - await this.#ensureCdp(); - return await this.#cdp.openThread(threadId, options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.openThread(threadId); - } + await this.#ensureCdp(); + return this.#cdp.openThread(threadId, options); } async status() { const cdpStatus = await this.#cdp.status(); @@ -10726,7 +10975,7 @@ var __webpack_modules__ = { port: this.#port, appServerFallback, reachable, - message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/deep-read' : cdpStatus.message, + message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/search/read' : cdpStatus.message, exitCode: reachable ? 0 : 1 }; } @@ -10751,6 +11000,18 @@ var __webpack_modules__ = { return false; } } + async #tryCdpList(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.listThreads(options); + } catch (error) { + if (isCdpFailure(error) || error instanceof _errors_js__rspack_import_2.EH) { + if (isCdpFailure(error)) this.#cdpConnected = false; + return null; + } + throw error; + } + } } function mergeThreadLists(appList, cdpList) { const cdpByKey = new Map(); @@ -10765,12 +11026,10 @@ var __webpack_modules__ = { return { ...thread, title: thread.title || cdp.title, - pinned: cdp.pinned, + pinned: thread.pinned || cdp.pinned, selected: cdp.selected, kind: cdp.kind || thread.kind, - ...cdp.project !== undefined ? { - project: cdp.project - } : {} + project: cdp.project ?? thread.project }; }); for (const thread of cdpList.threads){ @@ -10780,6 +11039,10 @@ var __webpack_modules__ = { return { backend: 'app-server', limit: appList.limit, + nextCursor: appList.nextCursor, + ...appList.query !== undefined ? { + query: appList.query + } : {}, threads: merged.slice(0, appList.limit) }; } @@ -10865,6 +11128,74 @@ var __webpack_modules__ = { tb: ()=>assertLoopbackHostname }); }, + "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var node_os__rspack_import_1 = __webpack_require__("node:os"); + var node_path__rspack_import_2 = __webpack_require__("node:path"); + var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; + function codexGlobalStatePath(env = process.env) { + const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); + return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); + } + function findRemoteThreadHostId(threadId, env = process.env) { + const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; + if (!bare) return null; + let raw; + try { + raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); + } catch { + return null; + } + let data; + try { + data = JSON.parse(raw); + } catch { + return null; + } + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + for (const [key, value] of Object.entries(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match) continue; + if (summariesIncludeThread(value, bare)) return match[1] ?? null; + } + return null; + } + function summariesIncludeThread(value, threadId) { + if (Array.isArray(value)) { + return value.some((entry)=>entryMentionsThread(entry, threadId)); + } + if (value && typeof value === 'object') { + const record = value; + if (threadId in record) return true; + if (Array.isArray(record.threads)) { + return record.threads.some((entry)=>entryMentionsThread(entry, threadId)); + } + if (Array.isArray(record.summaries)) { + return record.summaries.some((entry)=>entryMentionsThread(entry, threadId)); + } + return Object.values(record).some((entry)=>entryMentionsThread(entry, threadId)); + } + return false; + } + function entryMentionsThread(entry, threadId) { + if (typeof entry === 'string') return entry === threadId; + if (!entry || typeof entry !== 'object') return false; + const row = entry; + for (const key of [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]){ + if (row[key] === threadId) return true; + } + return false; + } + __webpack_require__.d(__webpack_exports__, { + X: ()=>findRemoteThreadHostId + }); + }, "./src/core/chatgpt-desktop/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_4 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _codex_contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); @@ -10879,6 +11210,11 @@ var __webpack_modules__ = { port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) }).strict(); + const searchThreadsSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + query: zod__rspack_import_4.YjP().min(1).max(512), + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + }).strict(); const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, @@ -10928,6 +11264,19 @@ var __webpack_modules__ = { exitCode: 1 }); } + if (error instanceof _errors_js__rspack_import_1.Rg) { + return asResult({ + delivery: error.delivery, + reason: error.reason, + code: error.code, + error: error.message, + threadId: error.threadId, + ...error.hostId ? { + hostId: error.hostId + } : {}, + exitCode: 1 + }); + } const base = (0, _codex_contract_js__rspack_import_0.DG)(error); if (error && typeof error === 'object' && 'code' in error) { return asResult({ @@ -10958,6 +11307,25 @@ var __webpack_modules__ = { return mapError(error); } } + async function searchThreadsOperation(input) { + try { + const out = await withAdapter(input.port, async (adapter)=>{ + if (typeof adapter.searchThreads !== 'function') { + throw new _errors_js__rspack_import_1.EH('searchThreads', 'adapter does not implement search'); + } + return adapter.searchThreads({ + query: input.query, + limit: input.limit + }); + }); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } async function readThreadOperation(input) { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ @@ -11012,10 +11380,11 @@ var __webpack_modules__ = { } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); if (Array.isArray(result.threads)) { - return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; + const via = result.query ? ` matching ${JSON.stringify(result.query)}` : ''; + return `${result.threads.length} threads${via} via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { - const mode = result.full ? 'full' : 'visible'; + const mode = result.full ? 'full' : 'page'; return `${result.turns.length} turns (${mode}) on ${result.threadId} via ${result.backend ?? 'unknown'}`; } if (result.delivery === 'accepted') { @@ -11033,7 +11402,8 @@ var __webpack_modules__ = { UK: ()=>readThreadOperation, UP: ()=>sendOperation, Uj: ()=>statusOperation, - tJ: ()=>listThreadsOperation + tJ: ()=>listThreadsOperation, + zg: ()=>searchThreadsOperation }, { FD: resultSchema }); @@ -11041,6 +11411,7 @@ var __webpack_modules__ = { "./src/core/chatgpt-desktop/thread-ids.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _cdp_dom_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); const LOCAL_THREAD_ID_PREFIX = 'local:'; + const HISTORY_CONTENT_TURN_PREFIX = 'history-content:turn:'; function isTemporaryDesktopThreadId(threadId) { return threadId.startsWith(_cdp_dom_js__rspack_import_0.hA); } @@ -11052,6 +11423,13 @@ var __webpack_modules__ = { } return threadId; } + function requireAppServerThreadId(threadId) { + const bare = toAppServerThreadId(threadId); + if (!bare) { + throw new Error(`No app-server thread id mapping for ${JSON.stringify(threadId)} ` + `(temporary Desktop rows need CDP; strip a leading "local:" for durable ids)`); + } + return bare; + } function toDesktopThreadId(threadId) { if (!threadId || isTemporaryDesktopThreadId(threadId)) return threadId; if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) return threadId; @@ -11062,22 +11440,22 @@ var __webpack_modules__ = { const right = toAppServerThreadId(b) ?? b; return left === right; } + function toDomTurnKey(turnId) { + if (!turnId) return turnId; + if (turnId.startsWith(HISTORY_CONTENT_TURN_PREFIX)) return turnId; + return `${HISTORY_CONTENT_TURN_PREFIX}${turnId}`; + } function appServerThreadIdCandidates(threadId) { - if (!threadId || isTemporaryDesktopThreadId(threadId)) return []; const bare = toAppServerThreadId(threadId); - const out = []; - const push = (id)=>{ - if (id && !out.includes(id)) out.push(id); - }; - push(bare); - push(threadId); - if (bare) push(toDesktopThreadId(bare)); - return out; + return bare ? [ + bare + ] : []; } __webpack_require__.d(__webpack_exports__, { BS: ()=>toDesktopThreadId, - EJ: ()=>appServerThreadIdCandidates, LV: ()=>threadIdsEquivalent, + NM: ()=>requireAppServerThreadId, + Sr: ()=>toDomTurnKey, nn: ()=>toAppServerThreadId, vr: ()=>isTemporaryDesktopThreadId }); @@ -38721,9 +39099,9 @@ var __webpack_modules__ = { try { var agent_bundle_launch_env_layer__rspack_import_0 = __webpack_require__("./.agent-bundle-virtual/bin-gbot-0.mjs"); var agent_bundle_cli_entry__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/cli-entry.js"); - var _agent_bundle_runtime__rspack_import_44 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); - var _agent_bundle_runtime__rspack_import_45 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); - var _agent_bundle_runtime__rspack_import_46 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/index.js"); + var _agent_bundle_runtime__rspack_import_45 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); + var _agent_bundle_runtime__rspack_import_46 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); + var _agent_bundle_runtime__rspack_import_47 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/index.js"); var node_url__rspack_import_2 = __webpack_require__("node:url"); var node_worker_threads__rspack_import_3 = __webpack_require__("node:worker_threads"); var _src_cli_approvals_list_tsx__rspack_import_4 = __webpack_require__("./src/cli/approvals/list.tsx"); @@ -38734,38 +39112,39 @@ var __webpack_modules__ = { var _src_cli_bots_list_tsx__rspack_import_9 = __webpack_require__("./src/cli/bots/list.tsx"); var _src_cli_bots_update_tsx__rspack_import_10 = __webpack_require__("./src/cli/bots/update.tsx"); var _src_cli_chatgpt_desktop_read_tsx__rspack_import_11 = __webpack_require__("./src/cli/chatgpt-desktop/read.tsx"); - var _src_cli_chatgpt_desktop_send_tsx__rspack_import_12 = __webpack_require__("./src/cli/chatgpt-desktop/send.tsx"); - var _src_cli_chatgpt_desktop_status_tsx__rspack_import_13 = __webpack_require__("./src/cli/chatgpt-desktop/status.tsx"); - var _src_cli_chatgpt_desktop_threads_tsx__rspack_import_14 = __webpack_require__("./src/cli/chatgpt-desktop/threads.tsx"); - var _src_cli_claude_send_tsx__rspack_import_15 = __webpack_require__("./src/cli/claude/send.tsx"); - var _src_cli_codex_bridge_respond_tsx__rspack_import_16 = __webpack_require__("./src/cli/codex/bridge/respond.tsx"); - var _src_cli_codex_bridge_run_tsx__rspack_import_17 = __webpack_require__("./src/cli/codex/bridge/run.tsx"); - var _src_cli_codex_bridge_start_tsx__rspack_import_18 = __webpack_require__("./src/cli/codex/bridge/start.tsx"); - var _src_cli_codex_bridge_status_tsx__rspack_import_19 = __webpack_require__("./src/cli/codex/bridge/status.tsx"); - var _src_cli_codex_bridge_stop_tsx__rspack_import_20 = __webpack_require__("./src/cli/codex/bridge/stop.tsx"); - var _src_cli_codex_desktop_shim_tsx__rspack_import_21 = __webpack_require__("./src/cli/codex/desktop-shim.tsx"); - var _src_cli_codex_list_threads_tsx__rspack_import_22 = __webpack_require__("./src/cli/codex/list-threads.tsx"); - var _src_cli_codex_queue_tsx__rspack_import_23 = __webpack_require__("./src/cli/codex/queue.tsx"); - var _src_cli_codex_send_tsx__rspack_import_24 = __webpack_require__("./src/cli/codex/send.tsx"); - var _src_cli_codex_status_tsx__rspack_import_25 = __webpack_require__("./src/cli/codex/status.tsx"); - var _src_cli_codex_wait_tsx__rspack_import_26 = __webpack_require__("./src/cli/codex/wait.tsx"); - var _src_cli_codex_watch_tsx__rspack_import_27 = __webpack_require__("./src/cli/codex/watch.tsx"); - var _src_cli_doctor_tsx__rspack_import_28 = __webpack_require__("./src/cli/doctor.tsx"); - var _src_cli_groups_add_tsx__rspack_import_29 = __webpack_require__("./src/cli/groups/add.tsx"); - var _src_cli_groups_create_tsx__rspack_import_30 = __webpack_require__("./src/cli/groups/create.tsx"); - var _src_cli_groups_delete_tsx__rspack_import_31 = __webpack_require__("./src/cli/groups/delete.tsx"); - var _src_cli_groups_get_tsx__rspack_import_32 = __webpack_require__("./src/cli/groups/get.tsx"); - var _src_cli_groups_list_tsx__rspack_import_33 = __webpack_require__("./src/cli/groups/list.tsx"); - var _src_cli_groups_members_tsx__rspack_import_34 = __webpack_require__("./src/cli/groups/members.tsx"); - var _src_cli_groups_remove_tsx__rspack_import_35 = __webpack_require__("./src/cli/groups/remove.tsx"); - var _src_cli_groups_set_tsx__rspack_import_36 = __webpack_require__("./src/cli/groups/set.tsx"); - var _src_cli_groups_update_tsx__rspack_import_37 = __webpack_require__("./src/cli/groups/update.tsx"); - var _src_cli_history_tsx__rspack_import_38 = __webpack_require__("./src/cli/history.tsx"); - var _src_cli_send_tsx__rspack_import_39 = __webpack_require__("./src/cli/send.tsx"); - var _src_cli_skills_add_tsx__rspack_import_40 = __webpack_require__("./src/cli/skills/add.tsx"); - var _src_cli_skills_list_tsx__rspack_import_41 = __webpack_require__("./src/cli/skills/list.tsx"); - var _src_cli_skills_remove_tsx__rspack_import_42 = __webpack_require__("./src/cli/skills/remove.tsx"); - var _src_cli_thread_tsx__rspack_import_43 = __webpack_require__("./src/cli/thread.tsx"); + var _src_cli_chatgpt_desktop_search_tsx__rspack_import_12 = __webpack_require__("./src/cli/chatgpt-desktop/search.tsx"); + var _src_cli_chatgpt_desktop_send_tsx__rspack_import_13 = __webpack_require__("./src/cli/chatgpt-desktop/send.tsx"); + var _src_cli_chatgpt_desktop_status_tsx__rspack_import_14 = __webpack_require__("./src/cli/chatgpt-desktop/status.tsx"); + var _src_cli_chatgpt_desktop_threads_tsx__rspack_import_15 = __webpack_require__("./src/cli/chatgpt-desktop/threads.tsx"); + var _src_cli_claude_send_tsx__rspack_import_16 = __webpack_require__("./src/cli/claude/send.tsx"); + var _src_cli_codex_bridge_respond_tsx__rspack_import_17 = __webpack_require__("./src/cli/codex/bridge/respond.tsx"); + var _src_cli_codex_bridge_run_tsx__rspack_import_18 = __webpack_require__("./src/cli/codex/bridge/run.tsx"); + var _src_cli_codex_bridge_start_tsx__rspack_import_19 = __webpack_require__("./src/cli/codex/bridge/start.tsx"); + var _src_cli_codex_bridge_status_tsx__rspack_import_20 = __webpack_require__("./src/cli/codex/bridge/status.tsx"); + var _src_cli_codex_bridge_stop_tsx__rspack_import_21 = __webpack_require__("./src/cli/codex/bridge/stop.tsx"); + var _src_cli_codex_desktop_shim_tsx__rspack_import_22 = __webpack_require__("./src/cli/codex/desktop-shim.tsx"); + var _src_cli_codex_list_threads_tsx__rspack_import_23 = __webpack_require__("./src/cli/codex/list-threads.tsx"); + var _src_cli_codex_queue_tsx__rspack_import_24 = __webpack_require__("./src/cli/codex/queue.tsx"); + var _src_cli_codex_send_tsx__rspack_import_25 = __webpack_require__("./src/cli/codex/send.tsx"); + var _src_cli_codex_status_tsx__rspack_import_26 = __webpack_require__("./src/cli/codex/status.tsx"); + var _src_cli_codex_wait_tsx__rspack_import_27 = __webpack_require__("./src/cli/codex/wait.tsx"); + var _src_cli_codex_watch_tsx__rspack_import_28 = __webpack_require__("./src/cli/codex/watch.tsx"); + var _src_cli_doctor_tsx__rspack_import_29 = __webpack_require__("./src/cli/doctor.tsx"); + var _src_cli_groups_add_tsx__rspack_import_30 = __webpack_require__("./src/cli/groups/add.tsx"); + var _src_cli_groups_create_tsx__rspack_import_31 = __webpack_require__("./src/cli/groups/create.tsx"); + var _src_cli_groups_delete_tsx__rspack_import_32 = __webpack_require__("./src/cli/groups/delete.tsx"); + var _src_cli_groups_get_tsx__rspack_import_33 = __webpack_require__("./src/cli/groups/get.tsx"); + var _src_cli_groups_list_tsx__rspack_import_34 = __webpack_require__("./src/cli/groups/list.tsx"); + var _src_cli_groups_members_tsx__rspack_import_35 = __webpack_require__("./src/cli/groups/members.tsx"); + var _src_cli_groups_remove_tsx__rspack_import_36 = __webpack_require__("./src/cli/groups/remove.tsx"); + var _src_cli_groups_set_tsx__rspack_import_37 = __webpack_require__("./src/cli/groups/set.tsx"); + var _src_cli_groups_update_tsx__rspack_import_38 = __webpack_require__("./src/cli/groups/update.tsx"); + var _src_cli_history_tsx__rspack_import_39 = __webpack_require__("./src/cli/history.tsx"); + var _src_cli_send_tsx__rspack_import_40 = __webpack_require__("./src/cli/send.tsx"); + var _src_cli_skills_add_tsx__rspack_import_41 = __webpack_require__("./src/cli/skills/add.tsx"); + var _src_cli_skills_list_tsx__rspack_import_42 = __webpack_require__("./src/cli/skills/list.tsx"); + var _src_cli_skills_remove_tsx__rspack_import_43 = __webpack_require__("./src/cli/skills/remove.tsx"); + var _src_cli_thread_tsx__rspack_import_44 = __webpack_require__("./src/cli/thread.tsx"); const route0 = Object.assign({}, Reflect.get(_src_cli_approvals_list_tsx__rspack_import_4, 'default'), _src_cli_approvals_list_tsx__rspack_import_4); const route1 = Object.assign({}, Reflect.get(_src_cli_approvals_respond_tsx__rspack_import_5, 'default'), _src_cli_approvals_respond_tsx__rspack_import_5); const route2 = Object.assign({}, Reflect.get(_src_cli_bots_create_tsx__rspack_import_6, 'default'), _src_cli_bots_create_tsx__rspack_import_6); @@ -38774,39 +39153,40 @@ var __webpack_modules__ = { const route5 = Object.assign({}, Reflect.get(_src_cli_bots_list_tsx__rspack_import_9, 'default'), _src_cli_bots_list_tsx__rspack_import_9); const route6 = Object.assign({}, Reflect.get(_src_cli_bots_update_tsx__rspack_import_10, 'default'), _src_cli_bots_update_tsx__rspack_import_10); const route7 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_read_tsx__rspack_import_11, 'default'), _src_cli_chatgpt_desktop_read_tsx__rspack_import_11); - const route8 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_send_tsx__rspack_import_12, 'default'), _src_cli_chatgpt_desktop_send_tsx__rspack_import_12); - const route9 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_status_tsx__rspack_import_13, 'default'), _src_cli_chatgpt_desktop_status_tsx__rspack_import_13); - const route10 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_threads_tsx__rspack_import_14, 'default'), _src_cli_chatgpt_desktop_threads_tsx__rspack_import_14); - const route11 = Object.assign({}, Reflect.get(_src_cli_claude_send_tsx__rspack_import_15, 'default'), _src_cli_claude_send_tsx__rspack_import_15); - const route12 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_respond_tsx__rspack_import_16, 'default'), _src_cli_codex_bridge_respond_tsx__rspack_import_16); - const route13 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_run_tsx__rspack_import_17, 'default'), _src_cli_codex_bridge_run_tsx__rspack_import_17); - const route14 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_start_tsx__rspack_import_18, 'default'), _src_cli_codex_bridge_start_tsx__rspack_import_18); - const route15 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_status_tsx__rspack_import_19, 'default'), _src_cli_codex_bridge_status_tsx__rspack_import_19); - const route16 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_stop_tsx__rspack_import_20, 'default'), _src_cli_codex_bridge_stop_tsx__rspack_import_20); - const route17 = Object.assign({}, Reflect.get(_src_cli_codex_desktop_shim_tsx__rspack_import_21, 'default'), _src_cli_codex_desktop_shim_tsx__rspack_import_21); - const route18 = Object.assign({}, Reflect.get(_src_cli_codex_list_threads_tsx__rspack_import_22, 'default'), _src_cli_codex_list_threads_tsx__rspack_import_22); - const route19 = Object.assign({}, Reflect.get(_src_cli_codex_queue_tsx__rspack_import_23, 'default'), _src_cli_codex_queue_tsx__rspack_import_23); - const route20 = Object.assign({}, Reflect.get(_src_cli_codex_send_tsx__rspack_import_24, 'default'), _src_cli_codex_send_tsx__rspack_import_24); - const route21 = Object.assign({}, Reflect.get(_src_cli_codex_status_tsx__rspack_import_25, 'default'), _src_cli_codex_status_tsx__rspack_import_25); - const route22 = Object.assign({}, Reflect.get(_src_cli_codex_wait_tsx__rspack_import_26, 'default'), _src_cli_codex_wait_tsx__rspack_import_26); - const route23 = Object.assign({}, Reflect.get(_src_cli_codex_watch_tsx__rspack_import_27, 'default'), _src_cli_codex_watch_tsx__rspack_import_27); - const route24 = Object.assign({}, Reflect.get(_src_cli_doctor_tsx__rspack_import_28, 'default'), _src_cli_doctor_tsx__rspack_import_28); - const route25 = Object.assign({}, Reflect.get(_src_cli_groups_add_tsx__rspack_import_29, 'default'), _src_cli_groups_add_tsx__rspack_import_29); - const route26 = Object.assign({}, Reflect.get(_src_cli_groups_create_tsx__rspack_import_30, 'default'), _src_cli_groups_create_tsx__rspack_import_30); - const route27 = Object.assign({}, Reflect.get(_src_cli_groups_delete_tsx__rspack_import_31, 'default'), _src_cli_groups_delete_tsx__rspack_import_31); - const route28 = Object.assign({}, Reflect.get(_src_cli_groups_get_tsx__rspack_import_32, 'default'), _src_cli_groups_get_tsx__rspack_import_32); - const route29 = Object.assign({}, Reflect.get(_src_cli_groups_list_tsx__rspack_import_33, 'default'), _src_cli_groups_list_tsx__rspack_import_33); - const route30 = Object.assign({}, Reflect.get(_src_cli_groups_members_tsx__rspack_import_34, 'default'), _src_cli_groups_members_tsx__rspack_import_34); - const route31 = Object.assign({}, Reflect.get(_src_cli_groups_remove_tsx__rspack_import_35, 'default'), _src_cli_groups_remove_tsx__rspack_import_35); - const route32 = Object.assign({}, Reflect.get(_src_cli_groups_set_tsx__rspack_import_36, 'default'), _src_cli_groups_set_tsx__rspack_import_36); - const route33 = Object.assign({}, Reflect.get(_src_cli_groups_update_tsx__rspack_import_37, 'default'), _src_cli_groups_update_tsx__rspack_import_37); - const route34 = Object.assign({}, Reflect.get(_src_cli_history_tsx__rspack_import_38, 'default'), _src_cli_history_tsx__rspack_import_38); - const route35 = Object.assign({}, Reflect.get(_src_cli_send_tsx__rspack_import_39, 'default'), _src_cli_send_tsx__rspack_import_39); - const route36 = Object.assign({}, Reflect.get(_src_cli_skills_add_tsx__rspack_import_40, 'default'), _src_cli_skills_add_tsx__rspack_import_40); - const route37 = Object.assign({}, Reflect.get(_src_cli_skills_list_tsx__rspack_import_41, 'default'), _src_cli_skills_list_tsx__rspack_import_41); - const route38 = Object.assign({}, Reflect.get(_src_cli_skills_remove_tsx__rspack_import_42, 'default'), _src_cli_skills_remove_tsx__rspack_import_42); - const route39 = Object.assign({}, Reflect.get(_src_cli_thread_tsx__rspack_import_43, 'default'), _src_cli_thread_tsx__rspack_import_43); - const pluginRoot = (0, _agent_bundle_runtime__rspack_import_44.E7)({ + const route8 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_search_tsx__rspack_import_12, 'default'), _src_cli_chatgpt_desktop_search_tsx__rspack_import_12); + const route9 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_send_tsx__rspack_import_13, 'default'), _src_cli_chatgpt_desktop_send_tsx__rspack_import_13); + const route10 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_status_tsx__rspack_import_14, 'default'), _src_cli_chatgpt_desktop_status_tsx__rspack_import_14); + const route11 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_threads_tsx__rspack_import_15, 'default'), _src_cli_chatgpt_desktop_threads_tsx__rspack_import_15); + const route12 = Object.assign({}, Reflect.get(_src_cli_claude_send_tsx__rspack_import_16, 'default'), _src_cli_claude_send_tsx__rspack_import_16); + const route13 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_respond_tsx__rspack_import_17, 'default'), _src_cli_codex_bridge_respond_tsx__rspack_import_17); + const route14 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_run_tsx__rspack_import_18, 'default'), _src_cli_codex_bridge_run_tsx__rspack_import_18); + const route15 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_start_tsx__rspack_import_19, 'default'), _src_cli_codex_bridge_start_tsx__rspack_import_19); + const route16 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_status_tsx__rspack_import_20, 'default'), _src_cli_codex_bridge_status_tsx__rspack_import_20); + const route17 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_stop_tsx__rspack_import_21, 'default'), _src_cli_codex_bridge_stop_tsx__rspack_import_21); + const route18 = Object.assign({}, Reflect.get(_src_cli_codex_desktop_shim_tsx__rspack_import_22, 'default'), _src_cli_codex_desktop_shim_tsx__rspack_import_22); + const route19 = Object.assign({}, Reflect.get(_src_cli_codex_list_threads_tsx__rspack_import_23, 'default'), _src_cli_codex_list_threads_tsx__rspack_import_23); + const route20 = Object.assign({}, Reflect.get(_src_cli_codex_queue_tsx__rspack_import_24, 'default'), _src_cli_codex_queue_tsx__rspack_import_24); + const route21 = Object.assign({}, Reflect.get(_src_cli_codex_send_tsx__rspack_import_25, 'default'), _src_cli_codex_send_tsx__rspack_import_25); + const route22 = Object.assign({}, Reflect.get(_src_cli_codex_status_tsx__rspack_import_26, 'default'), _src_cli_codex_status_tsx__rspack_import_26); + const route23 = Object.assign({}, Reflect.get(_src_cli_codex_wait_tsx__rspack_import_27, 'default'), _src_cli_codex_wait_tsx__rspack_import_27); + const route24 = Object.assign({}, Reflect.get(_src_cli_codex_watch_tsx__rspack_import_28, 'default'), _src_cli_codex_watch_tsx__rspack_import_28); + const route25 = Object.assign({}, Reflect.get(_src_cli_doctor_tsx__rspack_import_29, 'default'), _src_cli_doctor_tsx__rspack_import_29); + const route26 = Object.assign({}, Reflect.get(_src_cli_groups_add_tsx__rspack_import_30, 'default'), _src_cli_groups_add_tsx__rspack_import_30); + const route27 = Object.assign({}, Reflect.get(_src_cli_groups_create_tsx__rspack_import_31, 'default'), _src_cli_groups_create_tsx__rspack_import_31); + const route28 = Object.assign({}, Reflect.get(_src_cli_groups_delete_tsx__rspack_import_32, 'default'), _src_cli_groups_delete_tsx__rspack_import_32); + const route29 = Object.assign({}, Reflect.get(_src_cli_groups_get_tsx__rspack_import_33, 'default'), _src_cli_groups_get_tsx__rspack_import_33); + const route30 = Object.assign({}, Reflect.get(_src_cli_groups_list_tsx__rspack_import_34, 'default'), _src_cli_groups_list_tsx__rspack_import_34); + const route31 = Object.assign({}, Reflect.get(_src_cli_groups_members_tsx__rspack_import_35, 'default'), _src_cli_groups_members_tsx__rspack_import_35); + const route32 = Object.assign({}, Reflect.get(_src_cli_groups_remove_tsx__rspack_import_36, 'default'), _src_cli_groups_remove_tsx__rspack_import_36); + const route33 = Object.assign({}, Reflect.get(_src_cli_groups_set_tsx__rspack_import_37, 'default'), _src_cli_groups_set_tsx__rspack_import_37); + const route34 = Object.assign({}, Reflect.get(_src_cli_groups_update_tsx__rspack_import_38, 'default'), _src_cli_groups_update_tsx__rspack_import_38); + const route35 = Object.assign({}, Reflect.get(_src_cli_history_tsx__rspack_import_39, 'default'), _src_cli_history_tsx__rspack_import_39); + const route36 = Object.assign({}, Reflect.get(_src_cli_send_tsx__rspack_import_40, 'default'), _src_cli_send_tsx__rspack_import_40); + const route37 = Object.assign({}, Reflect.get(_src_cli_skills_add_tsx__rspack_import_41, 'default'), _src_cli_skills_add_tsx__rspack_import_41); + const route38 = Object.assign({}, Reflect.get(_src_cli_skills_list_tsx__rspack_import_42, 'default'), _src_cli_skills_list_tsx__rspack_import_42); + const route39 = Object.assign({}, Reflect.get(_src_cli_skills_remove_tsx__rspack_import_43, 'default'), _src_cli_skills_remove_tsx__rspack_import_43); + const route40 = Object.assign({}, Reflect.get(_src_cli_thread_tsx__rspack_import_44, 'default'), _src_cli_thread_tsx__rspack_import_44); + const pluginRoot = (0, _agent_bundle_runtime__rspack_import_45.E7)({ fallback: (0, node_url__rspack_import_2.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); @@ -38840,101 +39220,104 @@ var __webpack_modules__ = { "cli:chatgpt-desktop/read": Object.freeze({ module: route7 }), - "cli:chatgpt-desktop/send": Object.freeze({ + "cli:chatgpt-desktop/search": Object.freeze({ module: route8 }), - "cli:chatgpt-desktop/status": Object.freeze({ + "cli:chatgpt-desktop/send": Object.freeze({ module: route9 }), - "cli:chatgpt-desktop/threads": Object.freeze({ + "cli:chatgpt-desktop/status": Object.freeze({ module: route10 }), - "cli:claude/send": Object.freeze({ + "cli:chatgpt-desktop/threads": Object.freeze({ module: route11 }), - "cli:codex/bridge/respond": Object.freeze({ + "cli:claude/send": Object.freeze({ module: route12 }), - "cli:codex/bridge/run": Object.freeze({ + "cli:codex/bridge/respond": Object.freeze({ module: route13 }), - "cli:codex/bridge/start": Object.freeze({ + "cli:codex/bridge/run": Object.freeze({ module: route14 }), - "cli:codex/bridge/status": Object.freeze({ + "cli:codex/bridge/start": Object.freeze({ module: route15 }), - "cli:codex/bridge/stop": Object.freeze({ + "cli:codex/bridge/status": Object.freeze({ module: route16 }), - "cli:codex/desktop-shim": Object.freeze({ + "cli:codex/bridge/stop": Object.freeze({ module: route17 }), - "cli:codex/list-threads": Object.freeze({ + "cli:codex/desktop-shim": Object.freeze({ module: route18 }), - "cli:codex/queue": Object.freeze({ + "cli:codex/list-threads": Object.freeze({ module: route19 }), - "cli:codex/send": Object.freeze({ + "cli:codex/queue": Object.freeze({ module: route20 }), - "cli:codex/status": Object.freeze({ + "cli:codex/send": Object.freeze({ module: route21 }), - "cli:codex/wait": Object.freeze({ + "cli:codex/status": Object.freeze({ module: route22 }), - "cli:codex/watch": Object.freeze({ + "cli:codex/wait": Object.freeze({ module: route23 }), - "cli:doctor": Object.freeze({ + "cli:codex/watch": Object.freeze({ module: route24 }), - "cli:groups/add": Object.freeze({ + "cli:doctor": Object.freeze({ module: route25 }), - "cli:groups/create": Object.freeze({ + "cli:groups/add": Object.freeze({ module: route26 }), - "cli:groups/delete": Object.freeze({ + "cli:groups/create": Object.freeze({ module: route27 }), - "cli:groups/get": Object.freeze({ + "cli:groups/delete": Object.freeze({ module: route28 }), - "cli:groups/list": Object.freeze({ + "cli:groups/get": Object.freeze({ module: route29 }), - "cli:groups/members": Object.freeze({ + "cli:groups/list": Object.freeze({ module: route30 }), - "cli:groups/remove": Object.freeze({ + "cli:groups/members": Object.freeze({ module: route31 }), - "cli:groups/set": Object.freeze({ + "cli:groups/remove": Object.freeze({ module: route32 }), - "cli:groups/update": Object.freeze({ + "cli:groups/set": Object.freeze({ module: route33 }), - "cli:history": Object.freeze({ + "cli:groups/update": Object.freeze({ module: route34 }), - "cli:send": Object.freeze({ + "cli:history": Object.freeze({ module: route35 }), - "cli:skills/add": Object.freeze({ + "cli:send": Object.freeze({ module: route36 }), - "cli:skills/list": Object.freeze({ + "cli:skills/add": Object.freeze({ module: route37 }), - "cli:skills/remove": Object.freeze({ + "cli:skills/list": Object.freeze({ module: route38 }), - "cli:thread": Object.freeze({ + "cli:skills/remove": Object.freeze({ module: route39 + }), + "cli:thread": Object.freeze({ + module: route40 }) }); const commands = Object.freeze([ @@ -39302,7 +39685,7 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "Read a ChatGPT Desktop thread. Visible turns via CDP; --full / deep history via app-server (wheel crawl last-resort).", + "description": "Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.", "exitCode": "result", "options": [ { @@ -39355,6 +39738,44 @@ var __webpack_modules__ = { "rendered": true, "routeId": "cli:chatgpt-desktop/read" }, + { + "aliases": [], + "description": "Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.", + "exitCode": "result", + "options": [ + { + "defaultValue": 50, + "description": "Max matches (1-200)", + "key": "limit", + "kind": "number", + "option": "limit", + "repeated": false, + "required": false + }, + { + "description": "Local CDP port", + "key": "port", + "kind": "number", + "option": "port", + "repeated": false, + "required": false + }, + { + "key": "query", + "kind": "string", + "option": "query", + "positional": 0, + "repeated": false, + "required": true + } + ], + "path": [ + "chatgpt-desktop", + "search" + ], + "rendered": true, + "routeId": "cli:chatgpt-desktop/search" + }, { "aliases": [], "description": "Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .", @@ -41040,27 +41461,27 @@ var __webpack_modules__ = { instanceId: processLifetime.instanceId, pid: processLifetime.pid }; - const result = await (0, _agent_bundle_runtime__rspack_import_45.iC)({ + const result = await (0, _agent_bundle_runtime__rspack_import_46.iC)({ capabilities: { - command: (0, _agent_bundle_runtime__rspack_import_45.hU)(), - filesystem: (0, _agent_bundle_runtime__rspack_import_45.hU)(), - network: (0, _agent_bundle_runtime__rspack_import_45.hU)(), - projectRoot: (0, _agent_bundle_runtime__rspack_import_45.qC)({ + command: (0, _agent_bundle_runtime__rspack_import_46.hU)(), + filesystem: (0, _agent_bundle_runtime__rspack_import_46.hU)(), + network: (0, _agent_bundle_runtime__rspack_import_46.hU)(), + projectRoot: (0, _agent_bundle_runtime__rspack_import_46.qC)({ root: cwd }, 'derived') }, - host: (0, _agent_bundle_runtime__rspack_import_45.hU)('unsupported-surface'), + host: (0, _agent_bundle_runtime__rspack_import_46.hU)('unsupported-surface'), invocation: { kind: 'cli', operationId: command.routeId, surface: command.path.join(' ') }, - lineage: (0, _agent_bundle_runtime__rspack_import_45.hU)('unsupported-surface'), + lineage: (0, _agent_bundle_runtime__rspack_import_46.hU)('unsupported-surface'), plugin: pluginRoot.identity, process: processHit, signal: context.signal, - terminal: (0, _agent_bundle_runtime__rspack_import_45.qC)(context.terminal, 'native'), - workspace: (0, _agent_bundle_runtime__rspack_import_45.qC)({ + terminal: (0, _agent_bundle_runtime__rspack_import_46.qC)(context.terminal, 'native'), + workspace: (0, _agent_bundle_runtime__rspack_import_46.qC)({ root: cwd }, 'derived') }, async ()=>route.module.default({ @@ -41167,7 +41588,7 @@ var __webpack_modules__ = { return stream; } }); - const dispatcher = (0, _agent_bundle_runtime__rspack_import_46.jK)(host); + const dispatcher = (0, _agent_bundle_runtime__rspack_import_47.jK)(host); return Object.freeze({ close: async ()=>{ await worker.terminate(); @@ -42495,6 +42916,13 @@ var __webpack_modules__ = { if (value == null) return null; return typeof value === "string" ? singleLine(value) : value; } + function summarizeSection(section) { + if (!isObject(section) || typeof section.id !== "string" || !section.id) return null; + return { + id: singleLine(section.id), + name: lineField(section.name) + }; + } function summarizeThread(t) { if (!isObject(t) || typeof t.id !== "string" || !t.id) throw new CodexProtocolError("thread/list", "entry without a string `id`"); const type = isObject(t.status) && typeof t.status.type === "string" ? t.status.type : "unknown"; @@ -42506,7 +42934,13 @@ var __webpack_modules__ = { preview: typeof t.preview === "string" ? stripTerminalControls(t.preview) : "", cwd: lineField(t.cwd), source: sourceField(t.source), - updatedAt: typeof t.updatedAt === "number" ? t.updatedAt : null + createdAt: typeof t.createdAt === "number" ? t.createdAt : null, + updatedAt: typeof t.updatedAt === "number" ? t.updatedAt : null, + section: summarizeSection(t.section), + projectId: lineField(t.projectId), + modelProvider: lineField(t.modelProvider), + model: lineField(t.model), + originator: lineField(t.originator) }; } const THREAD_LIST_MAX_LIMIT = 200; @@ -42520,6 +42954,7 @@ var __webpack_modules__ = { const params = { limit, useStateDbOnly: true, + modelProviders: [], ...cursor !== undefined ? { cursor } : {} diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index a16c2ae..0c5d51b 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8086,79 +8086,74 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/app-server-fallback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); - var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); - async function appServerListThreads({ limit = 50 } = {}) { + var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _remote_threads_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + async function appServerListThreads({ limit = 50, cursor } = {}) { const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit + limit, + cursor }); return { backend: 'app-server', limit: out.limit, - threads: out.threads.map((thread)=>{ - const bare = String(thread.id ?? ''); - return { - threadId: bare ? (0, _thread_ids_js__rspack_import_1.BS)(bare) : '', - title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), - pinned: false, - selected: false, - kind: 'codex' - }; - }) + nextCursor: out.nextCursor ?? null, + threads: out.threads.map(mapListedThread) }; } - async function appServerReadThread({ threadId, limit = 100, full = false }) { - const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); - if (candidates.length === 0) { - throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); + async function appServerSearchThreads({ query, limit = 50 }) { + const needle = query.trim().toLowerCase(); + if (!needle) { + return appServerListThreads({ + limit + }); } - const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); - try { - let lastError; - for (const candidate of candidates){ - try { - const turns = await readTurnsForId(client, candidate, { - limit, - full - }); - return { - threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), - turns, - backend: 'app-server', - limit, - full - }; - } catch (error) { - lastError = error; - } + const matched = []; + let cursor; + for(let page = 0; page < 20 && matched.length < limit; page++){ + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit: 200, + cursor + }); + for (const thread of out.threads){ + const mapped = mapListedThread(thread); + if (threadMatchesQuery(mapped, needle)) matched.push(mapped); + if (matched.length >= limit) break; } - throw lastError instanceof Error ? lastError : new Error(`app-server thread read failed for ${threadId}`); - } finally{ - client.close(); + if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + cursor = out.nextCursor; } + return { + backend: 'app-server', + limit, + query, + nextCursor: null, + threads: matched.slice(0, limit) + }; } - async function appServerOpenThread(threadId) { - const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); - if (candidates.length === 0) { - throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); - } + async function appServerReadThread({ threadId, limit = 100, full = false }) { + const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { - let lastError; - for (const candidate of candidates){ - try { - await client.request('thread/resume', { - threadId: candidate, - excludeTurns: true - }); - return { - threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), - backend: 'app-server' - }; - } catch (error) { - lastError = error; - } - } - throw lastError instanceof Error ? lastError : new Error(`app-server thread/resume failed for ${threadId}`); + const meta = await readThreadMetadata(client, bare); + const turns = await listTurnsFull(client, bare, { + limit, + full + }); + return { + threadId: (0, _thread_ids_js__rspack_import_3.BS)(bare), + turns, + backend: 'app-server', + limit, + full, + title: meta.title, + cwd: meta.cwd, + status: meta.status, + modelProvider: meta.modelProvider, + model: meta.model + }; + } catch (error) { + throw maybeRemoteThreadError(error, bare); } finally{ client.close(); } @@ -8171,32 +8166,110 @@ var __webpack_modules__ = { socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined }; } - async function readTurnsForId(client, threadId, { limit, full }) { + function mapListedThread(thread) { + const bare = String(thread.id ?? ''); + const section = thread.section && typeof thread.section.id === 'string' ? { + id: thread.section.id, + name: thread.section.name ?? null + } : null; + const pinned = section?.id === 'Pinned' || section?.name === 'Pinned' || false; + return { + threadId: bare ? (0, _thread_ids_js__rspack_import_3.BS)(bare) : '', + title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), + pinned, + selected: false, + kind: 'codex', + preview: typeof thread.preview === 'string' ? thread.preview : undefined, + cwd: thread.cwd ?? null, + createdAt: thread.createdAt ?? null, + updatedAt: thread.updatedAt ?? null, + section, + projectId: thread.projectId ?? null, + project: thread.projectId ?? undefined, + status: thread.status, + modelProvider: thread.modelProvider ?? null, + model: thread.model ?? null, + originator: thread.originator ?? null + }; + } + function threadMatchesQuery(thread, needle) { + const haystacks = [ + thread.threadId, + thread.title, + thread.preview, + thread.cwd, + thread.project, + thread.projectId, + thread.model, + thread.modelProvider, + thread.originator, + thread.section?.name, + thread.section?.id + ]; + return haystacks.some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } + async function readThreadMetadata(client, threadId) { try { const read = await client.request('thread/read', { threadId }); - const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - if (Array.isArray(raw) && raw.length > 0) { - return sliceTurns(normalizeTurns(raw), { - limit, - full + const thread = read.thread && typeof read.thread === 'object' ? read.thread : {}; + const statusObj = thread.status; + const statusType = statusObj && typeof statusObj === 'object' && typeof statusObj.type === 'string' ? String(statusObj.type) : typeof thread.status === 'string' ? thread.status : undefined; + return { + title: typeof thread.name === 'string' ? thread.name : typeof thread.preview === 'string' ? thread.preview : undefined, + cwd: typeof thread.cwd === 'string' ? thread.cwd : null, + status: statusType, + modelProvider: typeof thread.modelProvider === 'string' ? thread.modelProvider : null, + model: typeof thread.model === 'string' ? thread.model : null + }; + } catch (error) { + throw maybeRemoteThreadError(error, threadId); + } + } + async function listTurnsFull(client, threadId, { limit, full }) { + const collected = []; + let cursor; + try { + for(let page = 0; page < 40; page++){ + const result = await client.request('thread/turns/list', { + threadId, + limit: 100, + itemsView: 'full', + ...cursor ? { + cursor + } : {} }); + if (!Array.isArray(result.data)) { + throw new Error(`thread/turns/list missing data array for ${threadId}`); + } + collected.push(...result.data); + if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; + cursor = result.nextCursor; + if (!full && collected.length >= limit) break; } - } catch {} - try { - const resumed = await client.request('thread/resume', { - threadId, - excludeTurns: false - }); - const raw = resumed.thread?.turns ?? resumed.turns ?? resumed.thread?.items ?? []; - if (Array.isArray(raw) && raw.length > 0) { - return sliceTurns(normalizeTurns(raw), { + } catch (error) { + if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + if (collected.length === 0) { + return listTurnsFallback(client, threadId, { limit, full }); } - } catch {} + throw error; + } + if (collected.length === 0) { + return listTurnsFallback(client, threadId, { + limit, + full + }); + } + return sliceTurns(normalizeTurns(collected), { + limit, + full + }); + } + async function listTurnsFallback(client, threadId, { limit, full }) { for (const method of [ 'thread/turns/list', 'thread/items/list' @@ -8204,14 +8277,16 @@ var __webpack_modules__ = { try { const collected = []; let cursor; - for(let page = 0; page < 20; page++){ - const result = await client.request(method, { + for(let page = 0; page < 40; page++){ + const params = { threadId, limit: 100, ...cursor ? { cursor } : {} - }); + }; + if (method === 'thread/turns/list') params.itemsView = 'full'; + const result = await client.request(method, params); if (!Array.isArray(result.data)) break; collected.push(...result.data); if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; @@ -8224,7 +8299,9 @@ var __webpack_modules__ = { full }); } - } catch {} + } catch (error) { + if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + } } throw new Error(`app-server has no turn history for thread ${threadId}`); } @@ -8238,24 +8315,116 @@ var __webpack_modules__ = { for (const [index, item] of raw.entries()){ if (!item || typeof item !== 'object') continue; const row = item; - const text = typeof row.text === 'string' ? row.text : typeof row.content === 'string' ? row.content : ''; - const type = String(row.type ?? row.role ?? ''); - let role = 'assistant'; - if (/user/i.test(type)) role = 'user'; - else if (/status|system|reasoning/i.test(type) && !text) role = 'status'; - turns.push({ - turnKey: String(row.id ?? row.turnId ?? index), - role, - text - }); + const id = String(row.id ?? row.turnId ?? index); + const items = Array.isArray(row.items) ? row.items : null; + if (items) { + turns.push(normalizeTurnWithItems(id, row, items)); + continue; + } + turns.push(normalizeLeafItem(id, row)); } return turns; } + function normalizeTurnWithItems(id, row, items) { + let userText = ''; + let assistantText = ''; + let toolText = ''; + let reasoningText = ''; + for (const entry of items){ + if (!entry || typeof entry !== 'object') continue; + const item = entry; + const type = String(item.type ?? item.role ?? ''); + const text = extractText(item); + if (/user/i.test(type)) userText = joinText(userText, text); + else if (/agent|assistant|message/i.test(type) && !/reasoning|tool/i.test(type)) { + assistantText = joinText(assistantText, text); + } else if (/tool/i.test(type)) toolText = joinText(toolText, text || type); + else if (/reasoning/i.test(type)) reasoningText = joinText(reasoningText, text); + } + let role = 'assistant'; + let text = assistantText || userText; + if (userText && !assistantText) { + role = 'user'; + text = userText; + } else if (!userText && !assistantText && toolText) { + role = 'tool'; + text = toolText; + } else if (!userText && !assistantText && reasoningText) { + role = 'reasoning'; + text = reasoningText; + } + return { + turnKey: (0, _thread_ids_js__rspack_import_3.Sr)(id), + role, + text, + ...userText ? { + userText + } : {}, + ...assistantText ? { + assistantText + } : {}, + startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, + endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + }; + } + function normalizeLeafItem(id, row) { + const text = extractText(row); + const type = String(row.type ?? row.role ?? ''); + let role = 'assistant'; + if (/user/i.test(type)) role = 'user'; + else if (/tool/i.test(type)) role = 'tool'; + else if (/reasoning/i.test(type)) role = 'reasoning'; + else if (/status|system/i.test(type) && !text) role = 'status'; + return { + turnKey: (0, _thread_ids_js__rspack_import_3.Sr)(id), + role, + text, + startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, + endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + }; + } + function extractText(row) { + if (typeof row.text === 'string') return row.text; + if (typeof row.content === 'string') return row.content; + if (typeof row.preview === 'string') return row.preview; + return ''; + } + function joinText(left, right) { + if (!right) return left; + if (!left) return right; + return `${left}\n${right}`; + } + function isThreadNotLoaded(error) { + const message = errorMessage(error); + return /thread not loaded|not loaded|invalid thread id/i.test(message); + } + function maybeRemoteThreadError(error, threadId) { + const message = errorMessage(error); + if (/thread not loaded|not loaded/i.test(message)) { + const hostId = (0, _remote_threads_js__rspack_import_2.X)(threadId); + return new _errors_js__rspack_import_1.Rg(threadId, hostId); + } + if (error instanceof Error) return error; + return new Error(message || `app-server error for thread ${threadId}`); + } + function errorMessage(error) { + if (!error) return ''; + if (typeof error === 'string') return error; + if (error instanceof Error) return error.message; + if (typeof error === 'object' && error && 'message' in error) { + return String(error.message); + } + if (typeof error === 'object' && error && 'rpc' in error) { + const rpc = error.rpc; + if (rpc && typeof rpc.message === 'string') return rpc.message; + } + return String(error); + } __webpack_require__.d(__webpack_exports__, { Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, - dM: ()=>appServerStatusProbe, - zu: ()=>appServerOpenThread + aI: ()=>appServerSearchThreads, + dM: ()=>appServerStatusProbe }); }, "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -9127,8 +9296,23 @@ var __webpack_modules__ = { this.name = 'CdpUnreachableError'; } } + class RemoteThreadNotLoadedError extends Error { + code = 'REMOTE_THREAD_NOT_LOADED'; + delivery = 'rejected'; + reason = 'remote-thread-not-loaded'; + threadId; + hostId; + constructor(threadId, hostId = null){ + const owner = hostId ? `owned by remote-control host ${JSON.stringify(hostId)}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ` + `${owner}. SSH remoting is not implemented in this adapter yet.`); + this.name = 'RemoteThreadNotLoadedError'; + this.threadId = threadId; + this.hostId = hostId; + } + } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, + Rg: ()=>RemoteThreadNotLoadedError, c$: ()=>CdpHostRejectedError, sO: ()=>CdpUnreachableError }); @@ -9141,8 +9325,8 @@ var __webpack_modules__ = { var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, + searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, - openThread: _app_server_fallback_js__rspack_import_1.zu, statusProbe: _app_server_fallback_js__rspack_import_1.dM }; class ChatGptDesktopFacade { @@ -9200,30 +9384,45 @@ var __webpack_modules__ = { if (appError) throw appError; throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); } + async searchThreads(options) { + try { + const appList = await this.#fallbacks.searchThreads(options); + const cdpList = await this.#tryCdpList({ + limit: options.limit + }); + if (cdpList) return mergeThreadLists(appList, cdpList); + return appList; + } catch (appError) { + const cdpList = await this.#tryCdpList({ + limit: options.limit + }); + if (!cdpList) throw appError; + const needle = options.query.trim().toLowerCase(); + return { + ...cdpList, + query: options.query, + threads: cdpList.threads.filter((thread)=>{ + if (!needle) return true; + return [ + thread.title, + thread.threadId, + thread.project + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + }) + }; + } + } async readThread(options) { const limit = options.limit ?? 100; const full = options.full ?? false; - const cdpConnected = await this.#tryEnsureCdp(); if ((0, _thread_ids_js__rspack_import_4.vr)(options.threadId)) { - if (!cdpConnected) { - throw new _errors_js__rspack_import_2.sO(`ChatGPT Desktop temporary thread ${options.threadId} requires CDP`); - } + await this.#ensureCdp(); return this.#cdp.readThread({ ...options, limit, full }); } - if (cdpConnected && !full) { - const visible = await this.#cdp.readThread({ - ...options, - limit, - full: false - }); - if (limit <= visible.turns.length) { - return visible; - } - } try { return await this.#fallbacks.readThread({ threadId: options.threadId, @@ -9231,14 +9430,13 @@ var __webpack_modules__ = { full }); } catch (appError) { - if (cdpConnected) { - return this.#cdp.readThread({ - ...options, - limit, - full: true - }); - } - throw appError; + const cdpConnected = await this.#tryEnsureCdp(); + if (!cdpConnected) throw appError; + return this.#cdp.readThread({ + ...options, + limit, + full: full || true + }); } } async sendMessage(options) { @@ -9250,13 +9448,8 @@ var __webpack_modules__ = { return this.#cdp.waitForReply(options); } async openThread(threadId, options) { - try { - await this.#ensureCdp(); - return await this.#cdp.openThread(threadId, options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.openThread(threadId); - } + await this.#ensureCdp(); + return this.#cdp.openThread(threadId, options); } async status() { const cdpStatus = await this.#cdp.status(); @@ -9274,7 +9467,7 @@ var __webpack_modules__ = { port: this.#port, appServerFallback, reachable, - message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/deep-read' : cdpStatus.message, + message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/search/read' : cdpStatus.message, exitCode: reachable ? 0 : 1 }; } @@ -9299,6 +9492,18 @@ var __webpack_modules__ = { return false; } } + async #tryCdpList(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.listThreads(options); + } catch (error) { + if (isCdpFailure(error) || error instanceof _errors_js__rspack_import_2.EH) { + if (isCdpFailure(error)) this.#cdpConnected = false; + return null; + } + throw error; + } + } } function mergeThreadLists(appList, cdpList) { const cdpByKey = new Map(); @@ -9313,12 +9518,10 @@ var __webpack_modules__ = { return { ...thread, title: thread.title || cdp.title, - pinned: cdp.pinned, + pinned: thread.pinned || cdp.pinned, selected: cdp.selected, kind: cdp.kind || thread.kind, - ...cdp.project !== undefined ? { - project: cdp.project - } : {} + project: cdp.project ?? thread.project }; }); for (const thread of cdpList.threads){ @@ -9328,6 +9531,10 @@ var __webpack_modules__ = { return { backend: 'app-server', limit: appList.limit, + nextCursor: appList.nextCursor, + ...appList.query !== undefined ? { + query: appList.query + } : {}, threads: merged.slice(0, appList.limit) }; } @@ -9413,6 +9620,74 @@ var __webpack_modules__ = { tb: ()=>assertLoopbackHostname }); }, + "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var node_os__rspack_import_1 = __webpack_require__("node:os"); + var node_path__rspack_import_2 = __webpack_require__("node:path"); + var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; + function codexGlobalStatePath(env = process.env) { + const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); + return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); + } + function findRemoteThreadHostId(threadId, env = process.env) { + const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; + if (!bare) return null; + let raw; + try { + raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); + } catch { + return null; + } + let data; + try { + data = JSON.parse(raw); + } catch { + return null; + } + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + for (const [key, value] of Object.entries(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match) continue; + if (summariesIncludeThread(value, bare)) return match[1] ?? null; + } + return null; + } + function summariesIncludeThread(value, threadId) { + if (Array.isArray(value)) { + return value.some((entry)=>entryMentionsThread(entry, threadId)); + } + if (value && typeof value === 'object') { + const record = value; + if (threadId in record) return true; + if (Array.isArray(record.threads)) { + return record.threads.some((entry)=>entryMentionsThread(entry, threadId)); + } + if (Array.isArray(record.summaries)) { + return record.summaries.some((entry)=>entryMentionsThread(entry, threadId)); + } + return Object.values(record).some((entry)=>entryMentionsThread(entry, threadId)); + } + return false; + } + function entryMentionsThread(entry, threadId) { + if (typeof entry === 'string') return entry === threadId; + if (!entry || typeof entry !== 'object') return false; + const row = entry; + for (const key of [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]){ + if (row[key] === threadId) return true; + } + return false; + } + __webpack_require__.d(__webpack_exports__, { + X: ()=>findRemoteThreadHostId + }); + }, "./src/core/chatgpt-desktop/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_4 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _codex_contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); @@ -9427,6 +9702,11 @@ var __webpack_modules__ = { port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) }).strict(); + const searchThreadsSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + query: zod__rspack_import_4.YjP().min(1).max(512), + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + }).strict(); const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, @@ -9476,6 +9756,19 @@ var __webpack_modules__ = { exitCode: 1 }); } + if (error instanceof _errors_js__rspack_import_1.Rg) { + return asResult({ + delivery: error.delivery, + reason: error.reason, + code: error.code, + error: error.message, + threadId: error.threadId, + ...error.hostId ? { + hostId: error.hostId + } : {}, + exitCode: 1 + }); + } const base = (0, _codex_contract_js__rspack_import_0.DG)(error); if (error && typeof error === 'object' && 'code' in error) { return asResult({ @@ -9506,6 +9799,25 @@ var __webpack_modules__ = { return mapError(error); } } + async function searchThreadsOperation(input) { + try { + const out = await withAdapter(input.port, async (adapter)=>{ + if (typeof adapter.searchThreads !== 'function') { + throw new _errors_js__rspack_import_1.EH('searchThreads', 'adapter does not implement search'); + } + return adapter.searchThreads({ + query: input.query, + limit: input.limit + }); + }); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } async function readThreadOperation(input) { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ @@ -9560,10 +9872,11 @@ var __webpack_modules__ = { } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); if (Array.isArray(result.threads)) { - return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; + const via = result.query ? ` matching ${JSON.stringify(result.query)}` : ''; + return `${result.threads.length} threads${via} via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { - const mode = result.full ? 'full' : 'visible'; + const mode = result.full ? 'full' : 'page'; return `${result.turns.length} turns (${mode}) on ${result.threadId} via ${result.backend ?? 'unknown'}`; } if (result.delivery === 'accepted') { @@ -9582,19 +9895,22 @@ var __webpack_modules__ = { UP: ()=>sendOperation, Uj: ()=>statusOperation, Zg: ()=>waitReplyOperation, - tJ: ()=>listThreadsOperation + tJ: ()=>listThreadsOperation, + zg: ()=>searchThreadsOperation }, { FC: listThreadsSchema, FD: resultSchema, Fn: waitReplySchema, Wi: sendSchema, aW: statusSchema, + nl: searchThreadsSchema, so: readThreadSchema }); }, "./src/core/chatgpt-desktop/thread-ids.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _cdp_dom_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); const LOCAL_THREAD_ID_PREFIX = 'local:'; + const HISTORY_CONTENT_TURN_PREFIX = 'history-content:turn:'; function isTemporaryDesktopThreadId(threadId) { return threadId.startsWith(_cdp_dom_js__rspack_import_0.hA); } @@ -9606,6 +9922,13 @@ var __webpack_modules__ = { } return threadId; } + function requireAppServerThreadId(threadId) { + const bare = toAppServerThreadId(threadId); + if (!bare) { + throw new Error(`No app-server thread id mapping for ${JSON.stringify(threadId)} ` + `(temporary Desktop rows need CDP; strip a leading "local:" for durable ids)`); + } + return bare; + } function toDesktopThreadId(threadId) { if (!threadId || isTemporaryDesktopThreadId(threadId)) return threadId; if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) return threadId; @@ -9616,22 +9939,22 @@ var __webpack_modules__ = { const right = toAppServerThreadId(b) ?? b; return left === right; } + function toDomTurnKey(turnId) { + if (!turnId) return turnId; + if (turnId.startsWith(HISTORY_CONTENT_TURN_PREFIX)) return turnId; + return `${HISTORY_CONTENT_TURN_PREFIX}${turnId}`; + } function appServerThreadIdCandidates(threadId) { - if (!threadId || isTemporaryDesktopThreadId(threadId)) return []; const bare = toAppServerThreadId(threadId); - const out = []; - const push = (id)=>{ - if (id && !out.includes(id)) out.push(id); - }; - push(bare); - push(threadId); - if (bare) push(toDesktopThreadId(bare)); - return out; + return bare ? [ + bare + ] : []; } __webpack_require__.d(__webpack_exports__, { BS: ()=>toDesktopThreadId, - EJ: ()=>appServerThreadIdCandidates, LV: ()=>threadIdsEquivalent, + NM: ()=>requireAppServerThreadId, + Sr: ()=>toDomTurnKey, nn: ()=>toAppServerThreadId, vr: ()=>isTemporaryDesktopThreadId }); @@ -10206,7 +10529,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List ChatGPT Desktop threads via the Codex app-server when available (thread/list), merging CDP-only sidebar fields (pinned, selected, project, kind) when CDP is connected. Desktop local: maps to bare app-server ids. Result includes backend.', + description: 'List ChatGPT Desktop / Codex threads via app-server thread/list (modelProviders:[], useStateDbOnly). Merges CDP-only UI fields (selected, pinned overlay) when CDP is connected. Desktop local: strips to bare app-server ids. Result includes backend.', annotations: { readOnlyHint: true }, @@ -10249,7 +10572,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Read a ChatGPT Desktop thread. Visible/recent turns use local CDP DOM harvest. full=true or a limit above the on-screen turns uses the Codex app-server (thread/read / resume); Desktop local: maps to the bare app-server id. DOM wheel crawl is only a fallback when app-server misses the thread. Result includes backend.', + description: 'Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. DOM harvest/wheel is fallback only when app-server is unavailable. Result includes backend.', annotations: { readOnlyHint: true }, @@ -10274,7 +10597,7 @@ var __webpack_modules__ = { }, full: { type: 'boolean', - description: 'When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.' + description: 'When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.' }, openTimeoutMs: { type: 'number', @@ -10300,6 +10623,55 @@ var __webpack_modules__ = { "default": __rspack_default_export }); }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop search threads', + description: 'Search ChatGPT Desktop / Codex threads through the local app-server (thread/list with modelProviders:[]), matching name/preview/cwd/project/model fields. Merges CDP selected/pinned when connected. Result includes backend.', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.nl, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number' + }, + query: { + type: 'string', + description: 'Case-insensitive substring over thread metadata.' + }, + limit: { + type: 'number', + description: 'Maximum matches (1-200).' + } + }, + required: [ + 'query' + ] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.zg)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.nl + }, { + "default": __rspack_default_export + }); + }, "./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); @@ -23094,6 +23466,13 @@ var __webpack_modules__ = { if (value == null) return null; return typeof value === "string" ? singleLine(value) : value; } + function summarizeSection(section) { + if (!isObject(section) || typeof section.id !== "string" || !section.id) return null; + return { + id: singleLine(section.id), + name: lineField(section.name) + }; + } function summarizeThread(t) { if (!isObject(t) || typeof t.id !== "string" || !t.id) throw new CodexProtocolError("thread/list", "entry without a string `id`"); const type = isObject(t.status) && typeof t.status.type === "string" ? t.status.type : "unknown"; @@ -23105,7 +23484,13 @@ var __webpack_modules__ = { preview: typeof t.preview === "string" ? stripTerminalControls(t.preview) : "", cwd: lineField(t.cwd), source: sourceField(t.source), - updatedAt: typeof t.updatedAt === "number" ? t.updatedAt : null + createdAt: typeof t.createdAt === "number" ? t.createdAt : null, + updatedAt: typeof t.updatedAt === "number" ? t.updatedAt : null, + section: summarizeSection(t.section), + projectId: lineField(t.projectId), + modelProvider: lineField(t.modelProvider), + model: lineField(t.model), + originator: lineField(t.originator) }; } const THREAD_LIST_MAX_LIMIT = 200; @@ -23119,6 +23504,7 @@ var __webpack_modules__ = { const params = { limit, useStateDbOnly: true, + modelProviders: [], ...cursor !== undefined ? { cursor } : {} @@ -26057,47 +26443,49 @@ function __webpack_require__(moduleId) { var __webpack_exports__ = {}; var node_worker_threads__rspack_import_0 = __webpack_require__("node:worker_threads"); var react__rspack_import_1 = __webpack_require__("./node_modules/react/react.react-server.js"); -var _agent_bundle_runtime_flight_server__rspack_import_24 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); -var _agent_bundle_runtime__rspack_import_21 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); -var _agent_bundle_runtime__rspack_import_22 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); -var _agent_bundle_runtime__rspack_import_23 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); +var _agent_bundle_runtime_flight_server__rspack_import_25 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); +var _agent_bundle_runtime__rspack_import_22 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); +var _agent_bundle_runtime__rspack_import_23 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); +var _agent_bundle_runtime__rspack_import_24 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); var node_url__rspack_import_2 = __webpack_require__("node:url"); var _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"); var _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); -var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); -var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); -var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); -var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); -var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); -var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); -var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); -var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); -var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); -var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); -var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); -var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); -var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); +var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); +var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); +var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); +var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); +var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); +var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); +var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); +var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); +var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); +var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); +var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); +var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); +var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_21 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); const route0 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3); const route1 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4); -const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_5); -const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_6); -const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_7); -const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_8); -const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_9); -const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_10); -const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_11); -const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_12); -const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_13); -const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_14); -const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_15); -const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_16); -const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_17); -const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_18); -const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_19); -const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_20); +const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_5); +const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_6); +const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_7); +const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_8); +const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_9); +const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_10); +const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_11); +const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_12); +const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_13); +const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_14); +const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_15); +const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_16); +const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_17); +const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_18); +const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_19); +const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_20); +const route18 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_21, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_21); globalThis.__rspack_rsc_manifest__ ??= Object.freeze({ clientManifest: Object.freeze({}) }); @@ -26109,7 +26497,7 @@ const processLifetime = { instanceId: crypto.randomUUID(), pid: process.pid }; -const pluginRoot = (0, _agent_bundle_runtime__rspack_import_21.E7)({ +const pluginRoot = (0, _agent_bundle_runtime__rspack_import_22.E7)({ fallback: (0, node_url__rspack_import_2.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); @@ -26120,7 +26508,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "List ChatGPT Desktop threads via the Codex app-server when available (thread/list), merging CDP-only sidebar fields (pinned, selected, project, kind) when CDP is connected. Desktop local: maps to bare app-server ids. Result includes backend.", + "description": "List ChatGPT Desktop / Codex threads via app-server thread/list (modelProviders:[], useStateDbOnly). Merges CDP-only UI fields (selected, pinned overlay) when CDP is connected. Desktop local: strips to bare app-server ids. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -26148,12 +26536,12 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Read a ChatGPT Desktop thread. Visible/recent turns use local CDP DOM harvest. full=true or a limit above the on-screen turns uses the Codex app-server (thread/read / resume); Desktop local: maps to the bare app-server id. DOM wheel crawl is only a fallback when app-server misses the thread. Result includes backend.", + "description": "Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. DOM harvest/wheel is fallback only when app-server is unavailable. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { "full": { - "description": "When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.", + "description": "When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.", "type": "boolean" }, "limit": { @@ -26187,6 +26575,40 @@ const routes = Object.freeze({ name: "chatgpt_desktop_read_thread", serverId: "mcp:grok-bot" }), + "tool:grok-bot/chatgpt_desktop_search_threads": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "Search ChatGPT Desktop / Codex threads through the local app-server (thread/list with modelProviders:[]), matching name/preview/cwd/project/model fields. Merges CDP selected/pinned when connected. Result includes backend.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum matches (1-200).", + "type": "number" + }, + "port": { + "type": "number" + }, + "query": { + "description": "Case-insensitive substring over thread metadata.", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "title": "ChatGPT Desktop search threads" + }, + id: "tool:grok-bot/chatgpt_desktop_search_threads", + kind: "tool", + module: route2, + name: "chatgpt_desktop_search_threads", + serverId: "mcp:grok-bot" + }), "tool:grok-bot/chatgpt_desktop_send": Object.freeze({ config: { "annotations": { @@ -26226,7 +26648,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_send", kind: "tool", - module: route2, + module: route3, name: "chatgpt_desktop_send", serverId: "mcp:grok-bot" }), @@ -26251,7 +26673,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_status", kind: "tool", - module: route3, + module: route4, name: "chatgpt_desktop_status", serverId: "mcp:grok-bot" }), @@ -26284,7 +26706,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_wait_reply", kind: "tool", - module: route4, + module: route5, name: "chatgpt_desktop_wait_reply", serverId: "mcp:grok-bot" }), @@ -26320,7 +26742,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/claude_send", kind: "tool", - module: route5, + module: route6, name: "claude_send", serverId: "mcp:grok-bot" }), @@ -26401,7 +26823,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_send", kind: "tool", - module: route6, + module: route7, name: "codex_send", serverId: "mcp:grok-bot" }), @@ -26435,7 +26857,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_threads", kind: "tool", - module: route7, + module: route8, name: "codex_threads", serverId: "mcp:grok-bot" }), @@ -26485,7 +26907,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_wait", kind: "tool", - module: route8, + module: route9, name: "codex_wait", serverId: "mcp:grok-bot" }), @@ -26528,7 +26950,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_watch", kind: "tool", - module: route9, + module: route10, name: "codex_watch", serverId: "mcp:grok-bot" }), @@ -26570,7 +26992,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_bridge_start", kind: "tool", - module: route10, + module: route11, name: "gbot_bridge_start", serverId: "mcp:grok-bot" }), @@ -26596,7 +27018,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_bridge_status", kind: "tool", - module: route11, + module: route12, name: "gbot_bridge_status", serverId: "mcp:grok-bot" }), @@ -26625,7 +27047,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_bridge_stop", kind: "tool", - module: route12, + module: route13, name: "gbot_bridge_stop", serverId: "mcp:grok-bot" }), @@ -26684,7 +27106,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_codex_respond", kind: "tool", - module: route13, + module: route14, name: "gbot_codex_respond", serverId: "mcp:grok-bot" }), @@ -26715,7 +27137,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_grok_approvals", kind: "tool", - module: route14, + module: route15, name: "gbot_grok_approvals", serverId: "mcp:grok-bot" }), @@ -26762,7 +27184,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_grok_respond", kind: "tool", - module: route15, + module: route16, name: "gbot_grok_respond", serverId: "mcp:grok-bot" }), @@ -26823,7 +27245,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_send", kind: "tool", - module: route16, + module: route17, name: "gbot_send", serverId: "mcp:grok-bot" }), @@ -26869,7 +27291,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_thread", kind: "tool", - module: route17, + module: route18, name: "gbot_thread", serverId: "mcp:grok-bot" }) @@ -26917,7 +27339,7 @@ const render = async (message)=>{ }; try { const plugin = message.plugin ?? pluginRoot.identity; - await (0, _agent_bundle_runtime__rspack_import_22.iC)({ + await (0, _agent_bundle_runtime__rspack_import_23.iC)({ ...message.actor === undefined ? {} : { actor: message.actor }, @@ -26931,7 +27353,7 @@ const render = async (message)=>{ operationId: route.id, surface: route.name }, - lineage: message.lineage ?? (0, _agent_bundle_runtime__rspack_import_22.hU)('not-provided'), + lineage: message.lineage ?? (0, _agent_bundle_runtime__rspack_import_23.hU)('not-provided'), plugin, progress: { report: async (update)=>{ @@ -26947,7 +27369,7 @@ const render = async (message)=>{ session: message.session }, signal: controller.signal, - terminal: message.terminal ?? (0, _agent_bundle_runtime__rspack_import_22.hU)('not-provided'), + terminal: message.terminal ?? (0, _agent_bundle_runtime__rspack_import_23.hU)('not-provided'), ...message.workspace === undefined ? {} : { workspace: message.workspace } @@ -26982,10 +27404,10 @@ const render = async (message)=>{ type: 'observed-render-start' }); const renderStartedAt = performance.now(); - const element = validationError === undefined ? composeLayouts(observedRoute, props, controller.signal) : (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_23.g.Result, null, (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_23.g.Error, { + const element = validationError === undefined ? composeLayouts(observedRoute, props, controller.signal) : (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_24.g.Result, null, (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_24.g.Error, { code: 'invalid-input' }, `Input validation error: ${validationError instanceof Error ? validationError.message : String(validationError)}`)); - const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_24.y)(element, { + const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_25.y)(element, { signal: controller.signal }); const reader = flight.getReader(); diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index 4c6f19e..afc8072 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -6494,79 +6494,74 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/app-server-fallback.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); - var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); - async function appServerListThreads({ limit = 50 } = {}) { + var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _remote_threads_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + async function appServerListThreads({ limit = 50, cursor } = {}) { const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit + limit, + cursor }); return { backend: 'app-server', limit: out.limit, - threads: out.threads.map((thread)=>{ - const bare = String(thread.id ?? ''); - return { - threadId: bare ? (0, _thread_ids_js__rspack_import_1.BS)(bare) : '', - title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), - pinned: false, - selected: false, - kind: 'codex' - }; - }) + nextCursor: out.nextCursor ?? null, + threads: out.threads.map(mapListedThread) }; } - async function appServerReadThread({ threadId, limit = 100, full = false }) { - const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); - if (candidates.length === 0) { - throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); + async function appServerSearchThreads({ query, limit = 50 }) { + const needle = query.trim().toLowerCase(); + if (!needle) { + return appServerListThreads({ + limit + }); } - const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); - try { - let lastError; - for (const candidate of candidates){ - try { - const turns = await readTurnsForId(client, candidate, { - limit, - full - }); - return { - threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), - turns, - backend: 'app-server', - limit, - full - }; - } catch (error) { - lastError = error; - } + const matched = []; + let cursor; + for(let page = 0; page < 20 && matched.length < limit; page++){ + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit: 200, + cursor + }); + for (const thread of out.threads){ + const mapped = mapListedThread(thread); + if (threadMatchesQuery(mapped, needle)) matched.push(mapped); + if (matched.length >= limit) break; } - throw lastError instanceof Error ? lastError : new Error(`app-server thread read failed for ${threadId}`); - } finally{ - client.close(); + if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + cursor = out.nextCursor; } + return { + backend: 'app-server', + limit, + query, + nextCursor: null, + threads: matched.slice(0, limit) + }; } - async function appServerOpenThread(threadId) { - const candidates = (0, _thread_ids_js__rspack_import_1.EJ)(threadId); - if (candidates.length === 0) { - throw new Error(`No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`); - } + async function appServerReadThread({ threadId, limit = 100, full = false }) { + const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { - let lastError; - for (const candidate of candidates){ - try { - await client.request('thread/resume', { - threadId: candidate, - excludeTurns: true - }); - return { - threadId: (0, _thread_ids_js__rspack_import_1.BS)(candidate), - backend: 'app-server' - }; - } catch (error) { - lastError = error; - } - } - throw lastError instanceof Error ? lastError : new Error(`app-server thread/resume failed for ${threadId}`); + const meta = await readThreadMetadata(client, bare); + const turns = await listTurnsFull(client, bare, { + limit, + full + }); + return { + threadId: (0, _thread_ids_js__rspack_import_3.BS)(bare), + turns, + backend: 'app-server', + limit, + full, + title: meta.title, + cwd: meta.cwd, + status: meta.status, + modelProvider: meta.modelProvider, + model: meta.model + }; + } catch (error) { + throw maybeRemoteThreadError(error, bare); } finally{ client.close(); } @@ -6579,32 +6574,110 @@ var __webpack_modules__ = { socketPath: typeof status.socketPath === 'string' ? status.socketPath : undefined }; } - async function readTurnsForId(client, threadId, { limit, full }) { + function mapListedThread(thread) { + const bare = String(thread.id ?? ''); + const section = thread.section && typeof thread.section.id === 'string' ? { + id: thread.section.id, + name: thread.section.name ?? null + } : null; + const pinned = section?.id === 'Pinned' || section?.name === 'Pinned' || false; + return { + threadId: bare ? (0, _thread_ids_js__rspack_import_3.BS)(bare) : '', + title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), + pinned, + selected: false, + kind: 'codex', + preview: typeof thread.preview === 'string' ? thread.preview : undefined, + cwd: thread.cwd ?? null, + createdAt: thread.createdAt ?? null, + updatedAt: thread.updatedAt ?? null, + section, + projectId: thread.projectId ?? null, + project: thread.projectId ?? undefined, + status: thread.status, + modelProvider: thread.modelProvider ?? null, + model: thread.model ?? null, + originator: thread.originator ?? null + }; + } + function threadMatchesQuery(thread, needle) { + const haystacks = [ + thread.threadId, + thread.title, + thread.preview, + thread.cwd, + thread.project, + thread.projectId, + thread.model, + thread.modelProvider, + thread.originator, + thread.section?.name, + thread.section?.id + ]; + return haystacks.some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } + async function readThreadMetadata(client, threadId) { try { const read = await client.request('thread/read', { threadId }); - const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - if (Array.isArray(raw) && raw.length > 0) { - return sliceTurns(normalizeTurns(raw), { - limit, - full + const thread = read.thread && typeof read.thread === 'object' ? read.thread : {}; + const statusObj = thread.status; + const statusType = statusObj && typeof statusObj === 'object' && typeof statusObj.type === 'string' ? String(statusObj.type) : typeof thread.status === 'string' ? thread.status : undefined; + return { + title: typeof thread.name === 'string' ? thread.name : typeof thread.preview === 'string' ? thread.preview : undefined, + cwd: typeof thread.cwd === 'string' ? thread.cwd : null, + status: statusType, + modelProvider: typeof thread.modelProvider === 'string' ? thread.modelProvider : null, + model: typeof thread.model === 'string' ? thread.model : null + }; + } catch (error) { + throw maybeRemoteThreadError(error, threadId); + } + } + async function listTurnsFull(client, threadId, { limit, full }) { + const collected = []; + let cursor; + try { + for(let page = 0; page < 40; page++){ + const result = await client.request('thread/turns/list', { + threadId, + limit: 100, + itemsView: 'full', + ...cursor ? { + cursor + } : {} }); + if (!Array.isArray(result.data)) { + throw new Error(`thread/turns/list missing data array for ${threadId}`); + } + collected.push(...result.data); + if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; + cursor = result.nextCursor; + if (!full && collected.length >= limit) break; } - } catch {} - try { - const resumed = await client.request('thread/resume', { - threadId, - excludeTurns: false - }); - const raw = resumed.thread?.turns ?? resumed.turns ?? resumed.thread?.items ?? []; - if (Array.isArray(raw) && raw.length > 0) { - return sliceTurns(normalizeTurns(raw), { + } catch (error) { + if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + if (collected.length === 0) { + return listTurnsFallback(client, threadId, { limit, full }); } - } catch {} + throw error; + } + if (collected.length === 0) { + return listTurnsFallback(client, threadId, { + limit, + full + }); + } + return sliceTurns(normalizeTurns(collected), { + limit, + full + }); + } + async function listTurnsFallback(client, threadId, { limit, full }) { for (const method of [ 'thread/turns/list', 'thread/items/list' @@ -6612,14 +6685,16 @@ var __webpack_modules__ = { try { const collected = []; let cursor; - for(let page = 0; page < 20; page++){ - const result = await client.request(method, { + for(let page = 0; page < 40; page++){ + const params = { threadId, limit: 100, ...cursor ? { cursor } : {} - }); + }; + if (method === 'thread/turns/list') params.itemsView = 'full'; + const result = await client.request(method, params); if (!Array.isArray(result.data)) break; collected.push(...result.data); if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; @@ -6632,7 +6707,9 @@ var __webpack_modules__ = { full }); } - } catch {} + } catch (error) { + if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + } } throw new Error(`app-server has no turn history for thread ${threadId}`); } @@ -6646,24 +6723,116 @@ var __webpack_modules__ = { for (const [index, item] of raw.entries()){ if (!item || typeof item !== 'object') continue; const row = item; - const text = typeof row.text === 'string' ? row.text : typeof row.content === 'string' ? row.content : ''; - const type = String(row.type ?? row.role ?? ''); - let role = 'assistant'; - if (/user/i.test(type)) role = 'user'; - else if (/status|system|reasoning/i.test(type) && !text) role = 'status'; - turns.push({ - turnKey: String(row.id ?? row.turnId ?? index), - role, - text - }); + const id = String(row.id ?? row.turnId ?? index); + const items = Array.isArray(row.items) ? row.items : null; + if (items) { + turns.push(normalizeTurnWithItems(id, row, items)); + continue; + } + turns.push(normalizeLeafItem(id, row)); } return turns; } + function normalizeTurnWithItems(id, row, items) { + let userText = ''; + let assistantText = ''; + let toolText = ''; + let reasoningText = ''; + for (const entry of items){ + if (!entry || typeof entry !== 'object') continue; + const item = entry; + const type = String(item.type ?? item.role ?? ''); + const text = extractText(item); + if (/user/i.test(type)) userText = joinText(userText, text); + else if (/agent|assistant|message/i.test(type) && !/reasoning|tool/i.test(type)) { + assistantText = joinText(assistantText, text); + } else if (/tool/i.test(type)) toolText = joinText(toolText, text || type); + else if (/reasoning/i.test(type)) reasoningText = joinText(reasoningText, text); + } + let role = 'assistant'; + let text = assistantText || userText; + if (userText && !assistantText) { + role = 'user'; + text = userText; + } else if (!userText && !assistantText && toolText) { + role = 'tool'; + text = toolText; + } else if (!userText && !assistantText && reasoningText) { + role = 'reasoning'; + text = reasoningText; + } + return { + turnKey: (0, _thread_ids_js__rspack_import_3.Sr)(id), + role, + text, + ...userText ? { + userText + } : {}, + ...assistantText ? { + assistantText + } : {}, + startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, + endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + }; + } + function normalizeLeafItem(id, row) { + const text = extractText(row); + const type = String(row.type ?? row.role ?? ''); + let role = 'assistant'; + if (/user/i.test(type)) role = 'user'; + else if (/tool/i.test(type)) role = 'tool'; + else if (/reasoning/i.test(type)) role = 'reasoning'; + else if (/status|system/i.test(type) && !text) role = 'status'; + return { + turnKey: (0, _thread_ids_js__rspack_import_3.Sr)(id), + role, + text, + startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, + endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + }; + } + function extractText(row) { + if (typeof row.text === 'string') return row.text; + if (typeof row.content === 'string') return row.content; + if (typeof row.preview === 'string') return row.preview; + return ''; + } + function joinText(left, right) { + if (!right) return left; + if (!left) return right; + return `${left}\n${right}`; + } + function isThreadNotLoaded(error) { + const message = errorMessage(error); + return /thread not loaded|not loaded|invalid thread id/i.test(message); + } + function maybeRemoteThreadError(error, threadId) { + const message = errorMessage(error); + if (/thread not loaded|not loaded/i.test(message)) { + const hostId = (0, _remote_threads_js__rspack_import_2.X)(threadId); + return new _errors_js__rspack_import_1.Rg(threadId, hostId); + } + if (error instanceof Error) return error; + return new Error(message || `app-server error for thread ${threadId}`); + } + function errorMessage(error) { + if (!error) return ''; + if (typeof error === 'string') return error; + if (error instanceof Error) return error.message; + if (typeof error === 'object' && error && 'message' in error) { + return String(error.message); + } + if (typeof error === 'object' && error && 'rpc' in error) { + const rpc = error.rpc; + if (rpc && typeof rpc.message === 'string') return rpc.message; + } + return String(error); + } __webpack_require__.d(__webpack_exports__, { Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, - dM: ()=>appServerStatusProbe, - zu: ()=>appServerOpenThread + aI: ()=>appServerSearchThreads, + dM: ()=>appServerStatusProbe }); }, "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -7535,8 +7704,23 @@ var __webpack_modules__ = { this.name = 'CdpUnreachableError'; } } + class RemoteThreadNotLoadedError extends Error { + code = 'REMOTE_THREAD_NOT_LOADED'; + delivery = 'rejected'; + reason = 'remote-thread-not-loaded'; + threadId; + hostId; + constructor(threadId, hostId = null){ + const owner = hostId ? `owned by remote-control host ${JSON.stringify(hostId)}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ` + `${owner}. SSH remoting is not implemented in this adapter yet.`); + this.name = 'RemoteThreadNotLoadedError'; + this.threadId = threadId; + this.hostId = hostId; + } + } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, + Rg: ()=>RemoteThreadNotLoadedError, c$: ()=>CdpHostRejectedError, sO: ()=>CdpUnreachableError }); @@ -7549,8 +7733,8 @@ var __webpack_modules__ = { var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, + searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, - openThread: _app_server_fallback_js__rspack_import_1.zu, statusProbe: _app_server_fallback_js__rspack_import_1.dM }; class ChatGptDesktopFacade { @@ -7608,30 +7792,45 @@ var __webpack_modules__ = { if (appError) throw appError; throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); } + async searchThreads(options) { + try { + const appList = await this.#fallbacks.searchThreads(options); + const cdpList = await this.#tryCdpList({ + limit: options.limit + }); + if (cdpList) return mergeThreadLists(appList, cdpList); + return appList; + } catch (appError) { + const cdpList = await this.#tryCdpList({ + limit: options.limit + }); + if (!cdpList) throw appError; + const needle = options.query.trim().toLowerCase(); + return { + ...cdpList, + query: options.query, + threads: cdpList.threads.filter((thread)=>{ + if (!needle) return true; + return [ + thread.title, + thread.threadId, + thread.project + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + }) + }; + } + } async readThread(options) { const limit = options.limit ?? 100; const full = options.full ?? false; - const cdpConnected = await this.#tryEnsureCdp(); if ((0, _thread_ids_js__rspack_import_4.vr)(options.threadId)) { - if (!cdpConnected) { - throw new _errors_js__rspack_import_2.sO(`ChatGPT Desktop temporary thread ${options.threadId} requires CDP`); - } + await this.#ensureCdp(); return this.#cdp.readThread({ ...options, limit, full }); } - if (cdpConnected && !full) { - const visible = await this.#cdp.readThread({ - ...options, - limit, - full: false - }); - if (limit <= visible.turns.length) { - return visible; - } - } try { return await this.#fallbacks.readThread({ threadId: options.threadId, @@ -7639,14 +7838,13 @@ var __webpack_modules__ = { full }); } catch (appError) { - if (cdpConnected) { - return this.#cdp.readThread({ - ...options, - limit, - full: true - }); - } - throw appError; + const cdpConnected = await this.#tryEnsureCdp(); + if (!cdpConnected) throw appError; + return this.#cdp.readThread({ + ...options, + limit, + full: full || true + }); } } async sendMessage(options) { @@ -7658,13 +7856,8 @@ var __webpack_modules__ = { return this.#cdp.waitForReply(options); } async openThread(threadId, options) { - try { - await this.#ensureCdp(); - return await this.#cdp.openThread(threadId, options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.openThread(threadId); - } + await this.#ensureCdp(); + return this.#cdp.openThread(threadId, options); } async status() { const cdpStatus = await this.#cdp.status(); @@ -7682,7 +7875,7 @@ var __webpack_modules__ = { port: this.#port, appServerFallback, reachable, - message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/deep-read' : cdpStatus.message, + message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/search/read' : cdpStatus.message, exitCode: reachable ? 0 : 1 }; } @@ -7707,6 +7900,18 @@ var __webpack_modules__ = { return false; } } + async #tryCdpList(options) { + try { + await this.#ensureCdp(); + return await this.#cdp.listThreads(options); + } catch (error) { + if (isCdpFailure(error) || error instanceof _errors_js__rspack_import_2.EH) { + if (isCdpFailure(error)) this.#cdpConnected = false; + return null; + } + throw error; + } + } } function mergeThreadLists(appList, cdpList) { const cdpByKey = new Map(); @@ -7721,12 +7926,10 @@ var __webpack_modules__ = { return { ...thread, title: thread.title || cdp.title, - pinned: cdp.pinned, + pinned: thread.pinned || cdp.pinned, selected: cdp.selected, kind: cdp.kind || thread.kind, - ...cdp.project !== undefined ? { - project: cdp.project - } : {} + project: cdp.project ?? thread.project }; }); for (const thread of cdpList.threads){ @@ -7736,6 +7939,10 @@ var __webpack_modules__ = { return { backend: 'app-server', limit: appList.limit, + nextCursor: appList.nextCursor, + ...appList.query !== undefined ? { + query: appList.query + } : {}, threads: merged.slice(0, appList.limit) }; } @@ -7821,6 +8028,74 @@ var __webpack_modules__ = { tb: ()=>assertLoopbackHostname }); }, + "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var node_os__rspack_import_1 = __webpack_require__("node:os"); + var node_path__rspack_import_2 = __webpack_require__("node:path"); + var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; + function codexGlobalStatePath(env = process.env) { + const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); + return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); + } + function findRemoteThreadHostId(threadId, env = process.env) { + const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; + if (!bare) return null; + let raw; + try { + raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); + } catch { + return null; + } + let data; + try { + data = JSON.parse(raw); + } catch { + return null; + } + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + for (const [key, value] of Object.entries(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match) continue; + if (summariesIncludeThread(value, bare)) return match[1] ?? null; + } + return null; + } + function summariesIncludeThread(value, threadId) { + if (Array.isArray(value)) { + return value.some((entry)=>entryMentionsThread(entry, threadId)); + } + if (value && typeof value === 'object') { + const record = value; + if (threadId in record) return true; + if (Array.isArray(record.threads)) { + return record.threads.some((entry)=>entryMentionsThread(entry, threadId)); + } + if (Array.isArray(record.summaries)) { + return record.summaries.some((entry)=>entryMentionsThread(entry, threadId)); + } + return Object.values(record).some((entry)=>entryMentionsThread(entry, threadId)); + } + return false; + } + function entryMentionsThread(entry, threadId) { + if (typeof entry === 'string') return entry === threadId; + if (!entry || typeof entry !== 'object') return false; + const row = entry; + for (const key of [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]){ + if (row[key] === threadId) return true; + } + return false; + } + __webpack_require__.d(__webpack_exports__, { + X: ()=>findRemoteThreadHostId + }); + }, "./src/core/chatgpt-desktop/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_4 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _codex_contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); @@ -7835,6 +8110,11 @@ var __webpack_modules__ = { port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) }).strict(); + const searchThreadsSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + query: zod__rspack_import_4.YjP().min(1).max(512), + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + }).strict(); const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, @@ -7884,6 +8164,19 @@ var __webpack_modules__ = { exitCode: 1 }); } + if (error instanceof _errors_js__rspack_import_1.Rg) { + return asResult({ + delivery: error.delivery, + reason: error.reason, + code: error.code, + error: error.message, + threadId: error.threadId, + ...error.hostId ? { + hostId: error.hostId + } : {}, + exitCode: 1 + }); + } const base = (0, _codex_contract_js__rspack_import_0.DG)(error); if (error && typeof error === 'object' && 'code' in error) { return asResult({ @@ -7914,6 +8207,25 @@ var __webpack_modules__ = { return mapError(error); } } + async function searchThreadsOperation(input) { + try { + const out = await withAdapter(input.port, async (adapter)=>{ + if (typeof adapter.searchThreads !== 'function') { + throw new _errors_js__rspack_import_1.EH('searchThreads', 'adapter does not implement search'); + } + return adapter.searchThreads({ + query: input.query, + limit: input.limit + }); + }); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } async function readThreadOperation(input) { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ @@ -7968,10 +8280,11 @@ var __webpack_modules__ = { } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); if (Array.isArray(result.threads)) { - return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; + const via = result.query ? ` matching ${JSON.stringify(result.query)}` : ''; + return `${result.threads.length} threads${via} via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { - const mode = result.full ? 'full' : 'visible'; + const mode = result.full ? 'full' : 'page'; return `${result.turns.length} turns (${mode}) on ${result.threadId} via ${result.backend ?? 'unknown'}`; } if (result.delivery === 'accepted') { @@ -7990,19 +8303,22 @@ var __webpack_modules__ = { UP: ()=>sendOperation, Uj: ()=>statusOperation, Zg: ()=>waitReplyOperation, - tJ: ()=>listThreadsOperation + tJ: ()=>listThreadsOperation, + zg: ()=>searchThreadsOperation }, { FC: listThreadsSchema, FD: resultSchema, Fn: waitReplySchema, Wi: sendSchema, aW: statusSchema, + nl: searchThreadsSchema, so: readThreadSchema }); }, "./src/core/chatgpt-desktop/thread-ids.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _cdp_dom_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); const LOCAL_THREAD_ID_PREFIX = 'local:'; + const HISTORY_CONTENT_TURN_PREFIX = 'history-content:turn:'; function isTemporaryDesktopThreadId(threadId) { return threadId.startsWith(_cdp_dom_js__rspack_import_0.hA); } @@ -8014,6 +8330,13 @@ var __webpack_modules__ = { } return threadId; } + function requireAppServerThreadId(threadId) { + const bare = toAppServerThreadId(threadId); + if (!bare) { + throw new Error(`No app-server thread id mapping for ${JSON.stringify(threadId)} ` + `(temporary Desktop rows need CDP; strip a leading "local:" for durable ids)`); + } + return bare; + } function toDesktopThreadId(threadId) { if (!threadId || isTemporaryDesktopThreadId(threadId)) return threadId; if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) return threadId; @@ -8024,22 +8347,22 @@ var __webpack_modules__ = { const right = toAppServerThreadId(b) ?? b; return left === right; } + function toDomTurnKey(turnId) { + if (!turnId) return turnId; + if (turnId.startsWith(HISTORY_CONTENT_TURN_PREFIX)) return turnId; + return `${HISTORY_CONTENT_TURN_PREFIX}${turnId}`; + } function appServerThreadIdCandidates(threadId) { - if (!threadId || isTemporaryDesktopThreadId(threadId)) return []; const bare = toAppServerThreadId(threadId); - const out = []; - const push = (id)=>{ - if (id && !out.includes(id)) out.push(id); - }; - push(bare); - push(threadId); - if (bare) push(toDesktopThreadId(bare)); - return out; + return bare ? [ + bare + ] : []; } __webpack_require__.d(__webpack_exports__, { BS: ()=>toDesktopThreadId, - EJ: ()=>appServerThreadIdCandidates, LV: ()=>threadIdsEquivalent, + NM: ()=>requireAppServerThreadId, + Sr: ()=>toDomTurnKey, nn: ()=>toAppServerThreadId, vr: ()=>isTemporaryDesktopThreadId }); @@ -8614,7 +8937,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List ChatGPT Desktop threads via the Codex app-server when available (thread/list), merging CDP-only sidebar fields (pinned, selected, project, kind) when CDP is connected. Desktop local: maps to bare app-server ids. Result includes backend.', + description: 'List ChatGPT Desktop / Codex threads via app-server thread/list (modelProviders:[], useStateDbOnly). Merges CDP-only UI fields (selected, pinned overlay) when CDP is connected. Desktop local: strips to bare app-server ids. Result includes backend.', annotations: { readOnlyHint: true }, @@ -8657,7 +8980,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Read a ChatGPT Desktop thread. Visible/recent turns use local CDP DOM harvest. full=true or a limit above the on-screen turns uses the Codex app-server (thread/read / resume); Desktop local: maps to the bare app-server id. DOM wheel crawl is only a fallback when app-server misses the thread. Result includes backend.', + description: 'Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. DOM harvest/wheel is fallback only when app-server is unavailable. Result includes backend.', annotations: { readOnlyHint: true }, @@ -8682,7 +9005,7 @@ var __webpack_modules__ = { }, full: { type: 'boolean', - description: 'When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.' + description: 'When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.' }, openTimeoutMs: { type: 'number', @@ -8708,6 +9031,55 @@ var __webpack_modules__ = { "default": __rspack_default_export }); }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop search threads', + description: 'Search ChatGPT Desktop / Codex threads through the local app-server (thread/list with modelProviders:[]), matching name/preview/cwd/project/model fields. Merges CDP selected/pinned when connected. Result includes backend.', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.nl, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number' + }, + query: { + type: 'string', + description: 'Case-insensitive substring over thread metadata.' + }, + limit: { + type: 'number', + description: 'Maximum matches (1-200).' + } + }, + required: [ + 'query' + ] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.zg)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.nl + }, { + "default": __rspack_default_export + }); + }, "./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); @@ -57943,54 +58315,56 @@ var __webpack_modules__ = { "./.agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var node_url__rspack_import_0 = __webpack_require__("node:url"); - var _agent_bundle_runtime__rspack_import_21 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); + var _agent_bundle_runtime__rspack_import_22 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); var agent_bundle_mcp_server_runtime__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/mcp-server-runtime.js"); - var _agent_bundle_runtime_lineage__rspack_import_22 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/lineage.js"); + var _agent_bundle_runtime_lineage__rspack_import_23 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/lineage.js"); var agent_bundle_mcp_apps__rspack_import_2 = __webpack_require__("./.agent-bundle-virtual/mcp-grok-bot-b8c2461e-0.mjs"); var _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"); var _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); - var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); - var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); - var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); - var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); - var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); - var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); - var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); - var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); - var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); - var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); - var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); - var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); - var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); + var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); + var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); + var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); + var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); + var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); + var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); + var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); + var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); + var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); + var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); + var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); + var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); + var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_21 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); const route0 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3); const route1 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4); - const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_5); - const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_6); - const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_7); - const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_8); - const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_9); - const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_10); - const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_11); - const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_12); - const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_13); - const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_14); - const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_15); - const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_16); - const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_17); - const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_18); - const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_19); - const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_20); + const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_5); + const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_6); + const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_7); + const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_8); + const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_9); + const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_10); + const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_11); + const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_12); + const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_13); + const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_14); + const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_15); + const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_16); + const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_17); + const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_18); + const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_19); + const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_20); + const route18 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_21, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_21); const ARTIFACT_EPOCH = "gbot@0.10.1"; - const pluginRoot = (0, _agent_bundle_runtime__rspack_import_21.E7)({ + const pluginRoot = (0, _agent_bundle_runtime__rspack_import_22.E7)({ fallback: (0, node_url__rspack_import_0.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); const openLineage = async ()=>({ dispose: async ()=>undefined, - registry: (0, _agent_bundle_runtime_lineage__rspack_import_22.Q5)() + registry: (0, _agent_bundle_runtime_lineage__rspack_import_23.Q5)() }); const routes = Object.freeze({ "tool:grok-bot/chatgpt_desktop_list_threads": Object.freeze({ @@ -57998,7 +58372,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "List ChatGPT Desktop threads via the Codex app-server when available (thread/list), merging CDP-only sidebar fields (pinned, selected, project, kind) when CDP is connected. Desktop local: maps to bare app-server ids. Result includes backend.", + "description": "List ChatGPT Desktop / Codex threads via app-server thread/list (modelProviders:[], useStateDbOnly). Merges CDP-only UI fields (selected, pinned overlay) when CDP is connected. Desktop local: strips to bare app-server ids. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -58025,12 +58399,12 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Read a ChatGPT Desktop thread. Visible/recent turns use local CDP DOM harvest. full=true or a limit above the on-screen turns uses the Codex app-server (thread/read / resume); Desktop local: maps to the bare app-server id. DOM wheel crawl is only a fallback when app-server misses the thread. Result includes backend.", + "description": "Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. DOM harvest/wheel is fallback only when app-server is unavailable. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { "full": { - "description": "When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.", + "description": "When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.", "type": "boolean" }, "limit": { @@ -58063,6 +58437,39 @@ var __webpack_modules__ = { module: route1, name: "chatgpt_desktop_read_thread" }), + "tool:grok-bot/chatgpt_desktop_search_threads": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "Search ChatGPT Desktop / Codex threads through the local app-server (thread/list with modelProviders:[]), matching name/preview/cwd/project/model fields. Merges CDP selected/pinned when connected. Result includes backend.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum matches (1-200).", + "type": "number" + }, + "port": { + "type": "number" + }, + "query": { + "description": "Case-insensitive substring over thread metadata.", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "title": "ChatGPT Desktop search threads" + }, + id: "tool:grok-bot/chatgpt_desktop_search_threads", + kind: "tool", + module: route2, + name: "chatgpt_desktop_search_threads" + }), "tool:grok-bot/chatgpt_desktop_send": Object.freeze({ config: { "annotations": { @@ -58102,7 +58509,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_send", kind: "tool", - module: route2, + module: route3, name: "chatgpt_desktop_send" }), "tool:grok-bot/chatgpt_desktop_status": Object.freeze({ @@ -58126,7 +58533,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_status", kind: "tool", - module: route3, + module: route4, name: "chatgpt_desktop_status" }), "tool:grok-bot/chatgpt_desktop_wait_reply": Object.freeze({ @@ -58158,7 +58565,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_wait_reply", kind: "tool", - module: route4, + module: route5, name: "chatgpt_desktop_wait_reply" }), "tool:grok-bot/claude_send": Object.freeze({ @@ -58193,7 +58600,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/claude_send", kind: "tool", - module: route5, + module: route6, name: "claude_send" }), "tool:grok-bot/codex_send": Object.freeze({ @@ -58273,7 +58680,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_send", kind: "tool", - module: route6, + module: route7, name: "codex_send" }), "tool:grok-bot/codex_threads": Object.freeze({ @@ -58306,7 +58713,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_threads", kind: "tool", - module: route7, + module: route8, name: "codex_threads" }), "tool:grok-bot/codex_wait": Object.freeze({ @@ -58355,7 +58762,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_wait", kind: "tool", - module: route8, + module: route9, name: "codex_wait" }), "tool:grok-bot/codex_watch": Object.freeze({ @@ -58397,7 +58804,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_watch", kind: "tool", - module: route9, + module: route10, name: "codex_watch" }), "tool:grok-bot/gbot_bridge_start": Object.freeze({ @@ -58438,7 +58845,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_bridge_start", kind: "tool", - module: route10, + module: route11, name: "gbot_bridge_start" }), "tool:grok-bot/gbot_bridge_status": Object.freeze({ @@ -58463,7 +58870,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_bridge_status", kind: "tool", - module: route11, + module: route12, name: "gbot_bridge_status" }), "tool:grok-bot/gbot_bridge_stop": Object.freeze({ @@ -58491,7 +58898,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_bridge_stop", kind: "tool", - module: route12, + module: route13, name: "gbot_bridge_stop" }), "tool:grok-bot/gbot_codex_respond": Object.freeze({ @@ -58549,7 +58956,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_codex_respond", kind: "tool", - module: route13, + module: route14, name: "gbot_codex_respond" }), "tool:grok-bot/gbot_grok_approvals": Object.freeze({ @@ -58579,7 +58986,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_grok_approvals", kind: "tool", - module: route14, + module: route15, name: "gbot_grok_approvals" }), "tool:grok-bot/gbot_grok_respond": Object.freeze({ @@ -58625,7 +59032,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_grok_respond", kind: "tool", - module: route15, + module: route16, name: "gbot_grok_respond" }), "tool:grok-bot/gbot_send": Object.freeze({ @@ -58685,7 +59092,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_send", kind: "tool", - module: route16, + module: route17, name: "gbot_send" }), "tool:grok-bot/gbot_thread": Object.freeze({ @@ -58730,7 +59137,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_thread", kind: "tool", - module: route17, + module: route18, name: "gbot_thread" }) }); @@ -60044,6 +60451,13 @@ var __webpack_modules__ = { if (value == null) return null; return typeof value === "string" ? singleLine(value) : value; } + function summarizeSection(section) { + if (!isObject(section) || typeof section.id !== "string" || !section.id) return null; + return { + id: singleLine(section.id), + name: lineField(section.name) + }; + } function summarizeThread(t) { if (!isObject(t) || typeof t.id !== "string" || !t.id) throw new CodexProtocolError("thread/list", "entry without a string `id`"); const type = isObject(t.status) && typeof t.status.type === "string" ? t.status.type : "unknown"; @@ -60055,7 +60469,13 @@ var __webpack_modules__ = { preview: typeof t.preview === "string" ? stripTerminalControls(t.preview) : "", cwd: lineField(t.cwd), source: sourceField(t.source), - updatedAt: typeof t.updatedAt === "number" ? t.updatedAt : null + createdAt: typeof t.createdAt === "number" ? t.createdAt : null, + updatedAt: typeof t.updatedAt === "number" ? t.updatedAt : null, + section: summarizeSection(t.section), + projectId: lineField(t.projectId), + modelProvider: lineField(t.modelProvider), + model: lineField(t.model), + originator: lineField(t.originator) }; } const THREAD_LIST_MAX_LIMIT = 200; @@ -60069,6 +60489,7 @@ var __webpack_modules__ = { const params = { limit, useStateDbOnly: true, + modelProviders: [], ...cursor !== undefined ? { cursor } : {} diff --git a/artifact/scripts/gbot-relay.mjs b/artifact/scripts/gbot-relay.mjs index d34d8e8..7131f93 100644 --- a/artifact/scripts/gbot-relay.mjs +++ b/artifact/scripts/gbot-relay.mjs @@ -22973,6 +22973,13 @@ var __webpack_modules__ = { if (value == null) return null; return typeof value === "string" ? singleLine(value) : value; } + function summarizeSection(section) { + if (!isObject(section) || typeof section.id !== "string" || !section.id) return null; + return { + id: singleLine(section.id), + name: lineField(section.name) + }; + } function summarizeThread(t) { if (!isObject(t) || typeof t.id !== "string" || !t.id) throw new CodexProtocolError("thread/list", "entry without a string `id`"); const type = isObject(t.status) && typeof t.status.type === "string" ? t.status.type : "unknown"; @@ -22984,7 +22991,13 @@ var __webpack_modules__ = { preview: typeof t.preview === "string" ? stripTerminalControls(t.preview) : "", cwd: lineField(t.cwd), source: sourceField(t.source), - updatedAt: typeof t.updatedAt === "number" ? t.updatedAt : null + createdAt: typeof t.createdAt === "number" ? t.createdAt : null, + updatedAt: typeof t.updatedAt === "number" ? t.updatedAt : null, + section: summarizeSection(t.section), + projectId: lineField(t.projectId), + modelProvider: lineField(t.modelProvider), + model: lineField(t.model), + originator: lineField(t.originator) }; } const THREAD_LIST_MAX_LIMIT = 200; @@ -22998,6 +23011,7 @@ var __webpack_modules__ = { const params = { limit, useStateDbOnly: true, + modelProviders: [], ...cursor !== undefined ? { cursor } : {} diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index 94a07c9..a15927c 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -5,6 +5,10 @@ Protocol on **127.0.0.1 only**. There is no remote transport. CDP/DOM details stay inside `src/core/chatgpt-desktop/`; MCP tools and CLI commands call the `ChatGptDesktopAdapter` surface. +List / search / read prefer the local Codex **app-server** (verified on +0.158.0). Send / new-thread-in-project / wait-for-reply / selected-thread stay +on CDP. DOM read is a fallback only when app-server is unavailable. + ## Enable remote debugging (macOS) Electron fuses on ChatGPT.app block Node inspect / `RunAsNode`, but they do @@ -28,6 +32,7 @@ Override the port with `CHATGPT_DESKTOP_CDP_PORT` or `--port`. ```sh gbot chatgpt-desktop status gbot chatgpt-desktop threads --limit 20 +gbot chatgpt-desktop search "launch" gbot chatgpt-desktop read gbot chatgpt-desktop send --thread-id "hello" gbot chatgpt-desktop send "start a new chat with this text" @@ -38,8 +43,9 @@ gbot chatgpt-desktop send "start a new chat with this text" | Tool | Role | | --- | --- | | `chatgpt_desktop_status` | CDP `/json/version` (+ optional attach) and app-server probe | -| `chatgpt_desktop_list_threads` | App-server `thread/list` when available; merges CDP sidebar fields | -| `chatgpt_desktop_read_thread` | Visible turns via CDP; deep/full history via app-server | +| `chatgpt_desktop_list_threads` | App-server `thread/list` (`modelProviders: []`); merge CDP UI fields | +| `chatgpt_desktop_search_threads` | App-server list + metadata filter | +| `chatgpt_desktop_read_thread` | App-server `thread/read` + `thread/turns/list` (`itemsView: "full"`) | | `chatgpt_desktop_send` | Composer submit over CDP (new-thread-in-project included) | | `chatgpt_desktop_wait_reply` | Poll for a new assistant turn over CDP | @@ -48,37 +54,60 @@ Every list/read/send/wait/open result includes `backend: "cdp" | "app-server"`. ## Thread id mapping Desktop sidebar rows expose `data-app-action-sidebar-thread-id` as -`local:`. The Codex app-server uses the bare `` -for `thread/list`, `thread/read`, and `thread/resume`. +`local:`. App-server rejects the prefixed form with +`invalid thread id`. Always strip `local:` before RPC calls +(`toAppServerThreadId` / `requireAppServerThreadId`). | Form | Example | Where | | --- | --- | --- | | Desktop sidebar | `local:11111111-1111-1111-1111-111111111111` | CDP DOM | -| App-server | `11111111-1111-1111-1111-111111111111` | `codex-bridge` / app-server | +| App-server | `11111111-1111-1111-1111-111111111111` | JSON-RPC | | Temporary (CDP-only) | `local:client-new-thread:…` | Composer before first reply | -Helpers in `thread-ids.ts` (`toAppServerThreadId`, `toDesktopThreadId`, -`appServerThreadIdCandidates`) accept either durable form. Temporary -`local:client-new-thread:…` ids do **not** map until -`data-response-annotation-conversation` resolves a real conversation id. -List/read results prefer the Desktop `local:…` form so callers can round-trip -the same id into send/wait. +Turn ids from app-server match DOM keys `history-content:turn:` +(`toDomTurnKey`). App-server history is usually richer than the virtualized +DOM (tool calls, reasoning, timing, and sometimes more turns). + +## App-server read protocol (0.158.0) + +1. `initialize` then `initialized` notification (via `openCodexSession`) +2. `thread/read` for **metadata only** (`includeTurns` is deprecated for + paginated threads) +3. Page history with `thread/turns/list` (`itemsView: "full"`, `cursor` / + `nextCursor`); `thread/items/list` is a fallback +4. **Do not** `thread/resume` for reads — resume attaches a live session + +`thread/list` filters to the current model provider by default. Pass +`modelProviders: []` for every provider, and `useStateDbOnly: true` for speed +(~0.02s; a cold rollout scan can take ~36s). Pagination uses `limit` / `cursor` +/ `nextCursor`. The same fix applies to `gbot codex list-threads` / +`codex_threads`. + +Surfaced list fields: `id`, `name`, `preview`, `cwd`, `createdAt` / +`updatedAt` (unix s), `section {id,name}` (Pinned → `pinned: true`), +`projectId`, `status`, `modelProvider`, `model`, `originator`. `archived` is a +list filter, not a field. + +### Remote-control threads + +Threads owned by another host are not loaded locally and return +`thread not loaded`. The adapter raises `RemoteThreadNotLoadedError` and, when +possible, names the owning `hostId` from +`~/.codex/.codex-global-state.json` keys `remote-thread-summaries-v3:`. +SSH remoting is **not** implemented in this PR (follow-up). ## Backend capability matrix | Operation | CDP | App-server | | --- | --- | --- | -| `status` | `/json/version` + attach | daemon probe (`codexStatus`) | -| `list_threads` | sidebar DOM (pinned/selected/project/kind) | primary inventory (`thread/list`) | -| `read_thread` (visible / limit ≤ on-screen) | harvest rendered turns | — | -| `read_thread` (full / limit > visible) | wheel crawl **fallback only** | primary (`thread/read`, resume+turns, turns/items list) | -| `open_thread` | click sidebar row | `thread/resume` fallback when CDP down | +| `status` | `/json/version` + attach | daemon probe | +| `list_threads` | merge selected / UI overlay | primary (`thread/list`, all providers) | +| `search_threads` | merge selected when connected | primary (list + filter) | +| `read_thread` | DOM harvest / wheel **fallback only** | primary (`thread/read` + turns/list) | +| `open_thread` (selected) | click sidebar row | **not used** (resume attaches) | | `send` / new-thread-in-project | composer + Enter / project button | **not used** | | `wait_reply` | Stop gone + final-assistant | **not used** | -List merges app-server rows with CDP-only fields (`pinned`, `selected`, -`project`, `kind`) when CDP is connected, and appends CDP-only temporary rows. - ## Target selection Prefer CDP `Target.getTargets`. The main window is `type: "page"` with URL @@ -96,13 +125,11 @@ All selectors live in `src/core/chatgpt-desktop/cdp-dom.ts`: - Reply text: last turn’s `[data-local-conversation-final-assistant=true] [data-markdown-text-style=assistant-message]` - New chat: `button[aria-label="Start new chat in "]` (preferred) or sidebar “New chat” - Conversation id: `[data-response-annotation-conversation]` (resolves `local:client-new-thread:…`) -- Open: click sidebar row, wait until “Loading task…” clears (default 90s) -- Visible read: harvest currently rendered turns (no wheel) -- Full-read fallback: mouseWheel (negative deltaY) on `[data-app-action-timeline-scroll]` (column-reverse); skip `history-gap:` keys — only when app-server misses the thread or is unreachable +- Open / selected: click sidebar row, wait until “Loading task…” clears (default 90s) +- Read fallback: harvest rendered turns; optional mouseWheel on `[data-app-action-timeline-scroll]` ## App-server reuse -Deep history and thread listing reuse the existing client in `codex-bridge.js` +List / search / read reuse the existing client in `codex-bridge.js` (`listCodexThreads`, `openCodexSession`, `codexStatus`) — no duplicated -JSON-RPC stack. Send / new-thread-in-project / wait-for-reply stay on CDP -because those Desktop UI actions are not app-server operations in this adapter. +JSON-RPC stack. Send / new-thread-in-project / wait-for-reply stay on CDP. diff --git a/src/cli/chatgpt-desktop/read.tsx b/src/cli/chatgpt-desktop/read.tsx index a71b738..ee3320a 100644 --- a/src/cli/chatgpt-desktop/read.tsx +++ b/src/cli/chatgpt-desktop/read.tsx @@ -10,7 +10,7 @@ import { export const config = { description: - 'Read a ChatGPT Desktop thread. Visible turns via CDP; --full / deep history via app-server (wheel crawl last-resort).', + 'Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.', exitCode: 'result', positionals: ['threadId'], inputJsonSchema: { diff --git a/src/cli/chatgpt-desktop/search.tsx b/src/cli/chatgpt-desktop/search.tsx new file mode 100644 index 0000000..100ac5d --- /dev/null +++ b/src/cli/chatgpt-desktop/search.tsx @@ -0,0 +1,46 @@ +import { Agent } from '@agent-bundle/runtime'; +import type { CliRouteConfig, CliRouteProps } from 'agent-bundle'; +import { z } from 'zod'; + +import { + resultSchema, + resultText, + searchThreadsOperation, +} from '../../core/chatgpt-desktop/routes.js'; + +export const config = { + description: + 'Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.', + exitCode: 'result', + positionals: ['query'], + inputJsonSchema: { + additionalProperties: false, + properties: { + limit: { default: 50, description: 'Max matches (1-200)', type: 'number' }, + port: { description: 'Local CDP port', type: 'number' }, + query: { type: 'string' }, + }, + required: ['query'], + type: 'object', + }, +} satisfies CliRouteConfig; + +export const inputSchema = z + .object({ + limit: z.number().int().min(1).max(200).default(50), + port: z.number().int().min(1).max(65535).optional(), + query: z.string().min(1).max(512), + }) + .strict(); +export { resultSchema }; + +export default async function chatgptDesktopSearch({ + input, +}: CliRouteProps) { + const out = await searchThreadsOperation(input); + return ( + + {resultText(out)} + + ); +} diff --git a/src/core/chatgpt-desktop/adapter.ts b/src/core/chatgpt-desktop/adapter.ts index a1b2d1a..f7c6efa 100644 --- a/src/core/chatgpt-desktop/adapter.ts +++ b/src/core/chatgpt-desktop/adapter.ts @@ -16,6 +16,11 @@ export interface ChatGptDesktopAdapter { connect(options: { port: number }): Promise; listTargets(): Promise; listThreads(options?: { limit?: number }): Promise; + /** Optional; facades that support app-server search implement this. */ + searchThreads?(options: { + query: string; + limit?: number; + }): Promise; readThread(options: { threadId: string; limit?: number; diff --git a/src/core/chatgpt-desktop/app-server-fallback.ts b/src/core/chatgpt-desktop/app-server-fallback.ts index c1e9dde..73337a6 100644 --- a/src/core/chatgpt-desktop/app-server-fallback.ts +++ b/src/core/chatgpt-desktop/app-server-fallback.ts @@ -1,8 +1,14 @@ /** - * App-server path for ChatGPT Desktop list/deep-read/open. + * App-server path for ChatGPT Desktop list / search / read. * Reuses the existing codex-bridge client — does not duplicate the WebSocket/JSON-RPC stack. * - * Send, new-thread-in-project, and wait-for-reply stay on CDP (see facade). + * Verified against Codex app-server 0.158.0: + * - initialize → initialized → thread/list | thread/read | thread/turns/list | thread/items/list + * - Do not use thread/resume for reads (it attaches a live session). + * - includeTurns on thread/read is deprecated for paginated threads; read metadata, + * then page with thread/turns/list (itemsView: "full"). + * + * Send, new-thread-in-project, wait-for-reply, and selected-thread stay on CDP (see facade). */ import { @@ -10,41 +16,66 @@ import { listCodexThreads, openCodexSession, } from '../codex-bridge.js'; +import { RemoteThreadNotLoadedError } from './errors.js'; +import { findRemoteThreadHostId } from './remote-threads.js'; import { - appServerThreadIdCandidates, + requireAppServerThreadId, toDesktopThreadId, + toDomTurnKey, } from './thread-ids.js'; import type { + ChatGptDesktopThread, + ChatGptDesktopTurn, ListThreadsResult, - OpenThreadResult, ReadThreadResult, } from './types.js'; export async function appServerListThreads({ limit = 50, + cursor, }: { limit?: number; + cursor?: string; } = {}): Promise { - const out = await listCodexThreads({ limit }); + const out = await listCodexThreads({ limit, cursor }); return { backend: 'app-server', limit: out.limit, - threads: out.threads.map((thread: { - id?: string; - name?: string; - preview?: string; - cwd?: string; - }) => { - const bare = String(thread.id ?? ''); - return { - // Present Desktop-form ids so callers can pass them straight back to read/send. - threadId: bare ? toDesktopThreadId(bare) : '', - title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), - pinned: false, - selected: false, - kind: 'codex', - }; - }), + nextCursor: out.nextCursor ?? null, + threads: out.threads.map(mapListedThread), + }; +} + +export async function appServerSearchThreads({ + query, + limit = 50, +}: { + query: string; + limit?: number; +}): Promise { + const needle = query.trim().toLowerCase(); + if (!needle) { + return appServerListThreads({ limit }); + } + const matched: ChatGptDesktopThread[] = []; + let cursor: string | undefined; + // Page the full inventory (modelProviders: [] is applied inside listCodexThreads). + for (let page = 0; page < 20 && matched.length < limit; page++) { + const out = await listCodexThreads({ limit: 200, cursor }); + for (const thread of out.threads) { + const mapped = mapListedThread(thread); + if (threadMatchesQuery(mapped, needle)) matched.push(mapped); + if (matched.length >= limit) break; + } + if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + cursor = out.nextCursor; + } + return { + backend: 'app-server', + limit, + query, + nextCursor: null, + threads: matched.slice(0, limit), }; } @@ -57,59 +88,26 @@ export async function appServerReadThread({ limit?: number; full?: boolean; }): Promise { - const candidates = appServerThreadIdCandidates(threadId); - if (candidates.length === 0) { - throw new Error( - `No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`, - ); - } - - const { client } = await openCodexSession(); - try { - let lastError: unknown; - for (const candidate of candidates) { - try { - const turns = await readTurnsForId(client, candidate, { limit, full }); - return { - threadId: toDesktopThreadId(candidate), - turns, - backend: 'app-server', - limit, - full, - }; - } catch (error) { - lastError = error; - } - } - throw lastError instanceof Error - ? lastError - : new Error(`app-server thread read failed for ${threadId}`); - } finally { - client.close(); - } -} - -export async function appServerOpenThread(threadId: string): Promise { - const candidates = appServerThreadIdCandidates(threadId); - if (candidates.length === 0) { - throw new Error( - `No app-server thread id mapping for ${threadId} (temporary Desktop rows need CDP)`, - ); - } + // Prefixed `local:` ids fail with `invalid thread id` — always strip first. + const bare = requireAppServerThreadId(threadId); const { client } = await openCodexSession(); try { - let lastError: unknown; - for (const candidate of candidates) { - try { - await client.request('thread/resume', { threadId: candidate, excludeTurns: true }); - return { threadId: toDesktopThreadId(candidate), backend: 'app-server' }; - } catch (error) { - lastError = error; - } - } - throw lastError instanceof Error - ? lastError - : new Error(`app-server thread/resume failed for ${threadId}`); + const meta = await readThreadMetadata(client, bare); + const turns = await listTurnsFull(client, bare, { limit, full }); + return { + threadId: toDesktopThreadId(bare), + turns, + backend: 'app-server', + limit, + full, + title: meta.title, + cwd: meta.cwd, + status: meta.status, + modelProvider: meta.modelProvider, + model: meta.model, + }; + } catch (error) { + throw maybeRemoteThreadError(error, bare); } finally { client.close(); } @@ -136,53 +134,166 @@ type AppServerClient = { request: (method: string, params?: Record) => Promise; }; -async function readTurnsForId( +type ListedThread = { + id?: string; + name?: string | null; + preview?: string; + cwd?: string | null; + createdAt?: number | null; + updatedAt?: number | null; + section?: { id?: string; name?: string | null } | null; + projectId?: string | null; + status?: string; + modelProvider?: string | null; + model?: string | null; + originator?: string | null; +}; + +function mapListedThread(thread: ListedThread): ChatGptDesktopThread { + const bare = String(thread.id ?? ''); + const section = + thread.section && typeof thread.section.id === 'string' + ? { id: thread.section.id, name: thread.section.name ?? null } + : null; + const pinned = + section?.id === 'Pinned' || + section?.name === 'Pinned' || + false; + return { + threadId: bare ? toDesktopThreadId(bare) : '', + title: String(thread.name || thread.preview || thread.cwd || thread.id || ''), + pinned, + selected: false, + kind: 'codex', + preview: typeof thread.preview === 'string' ? thread.preview : undefined, + cwd: thread.cwd ?? null, + createdAt: thread.createdAt ?? null, + updatedAt: thread.updatedAt ?? null, + section, + projectId: thread.projectId ?? null, + project: thread.projectId ?? undefined, + status: thread.status, + modelProvider: thread.modelProvider ?? null, + model: thread.model ?? null, + originator: thread.originator ?? null, + }; +} + +function threadMatchesQuery(thread: ChatGptDesktopThread, needle: string): boolean { + const haystacks = [ + thread.threadId, + thread.title, + thread.preview, + thread.cwd, + thread.project, + thread.projectId, + thread.model, + thread.modelProvider, + thread.originator, + thread.section?.name, + thread.section?.id, + ]; + return haystacks.some((value) => typeof value === 'string' && value.toLowerCase().includes(needle)); +} + +async function readThreadMetadata( client: AppServerClient, threadId: string, - { limit, full }: { limit: number; full: boolean }, -): Promise { - // Prefer thread/read (full history inspection). Fall back to resume-with-turns, - // then paginated turns/items lists — same client, no duplicated transport. +): Promise<{ + title?: string; + cwd?: string | null; + status?: string; + modelProvider?: string | null; + model?: string | null; +}> { try { + // Metadata only — includeTurns is deprecated for paginated threads. const read = await client.request('thread/read', { threadId }) as { - thread?: { turns?: unknown[]; items?: unknown[] }; - turns?: unknown[]; - items?: unknown[]; + thread?: Record; }; - const raw = read.thread?.turns ?? read.turns ?? read.thread?.items ?? read.items ?? []; - if (Array.isArray(raw) && raw.length > 0) { - return sliceTurns(normalizeTurns(raw), { limit, full }); - } - } catch { - // try resume / list below + const thread = read.thread && typeof read.thread === 'object' ? read.thread : {}; + const statusObj = thread.status; + const statusType = + statusObj && typeof statusObj === 'object' && typeof (statusObj as { type?: unknown }).type === 'string' + ? String((statusObj as { type: string }).type) + : typeof thread.status === 'string' + ? thread.status + : undefined; + return { + title: + typeof thread.name === 'string' + ? thread.name + : typeof thread.preview === 'string' + ? thread.preview + : undefined, + cwd: typeof thread.cwd === 'string' ? thread.cwd : null, + status: statusType, + modelProvider: typeof thread.modelProvider === 'string' ? thread.modelProvider : null, + model: typeof thread.model === 'string' ? thread.model : null, + }; + } catch (error) { + throw maybeRemoteThreadError(error, threadId); } +} +async function listTurnsFull( + client: AppServerClient, + threadId: string, + { limit, full }: { limit: number; full: boolean }, +): Promise { + const collected: unknown[] = []; + let cursor: string | undefined; try { - const resumed = await client.request('thread/resume', { - threadId, - excludeTurns: false, - }) as { - thread?: { turns?: unknown[]; items?: unknown[] }; - turns?: unknown[]; - }; - const raw = resumed.thread?.turns ?? resumed.turns ?? resumed.thread?.items ?? []; - if (Array.isArray(raw) && raw.length > 0) { - return sliceTurns(normalizeTurns(raw), { limit, full }); + for (let page = 0; page < 40; page++) { + const result = await client.request('thread/turns/list', { + threadId, + limit: 100, + itemsView: 'full', + ...(cursor ? { cursor } : {}), + }) as { data?: unknown[]; nextCursor?: string | null }; + if (!Array.isArray(result.data)) { + throw new Error(`thread/turns/list missing data array for ${threadId}`); + } + collected.push(...result.data); + if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; + cursor = result.nextCursor; + if (!full && collected.length >= limit) break; + } + } catch (error) { + if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + // Older daemons may lack itemsView; retry without it, then items/list. + if (collected.length === 0) { + return listTurnsFallback(client, threadId, { limit, full }); } - } catch { - // try list below + throw error; } + if (collected.length === 0) { + return listTurnsFallback(client, threadId, { limit, full }); + } + return sliceTurns(normalizeTurns(collected), { limit, full }); +} + +async function listTurnsFallback( + client: AppServerClient, + threadId: string, + { limit, full }: { limit: number; full: boolean }, +): Promise { for (const method of ['thread/turns/list', 'thread/items/list'] as const) { try { const collected: unknown[] = []; let cursor: string | undefined; - for (let page = 0; page < 20; page++) { - const result = await client.request(method, { + for (let page = 0; page < 40; page++) { + const params: Record = { threadId, limit: 100, ...(cursor ? { cursor } : {}), - }) as { data?: unknown[]; nextCursor?: string | null }; + }; + if (method === 'thread/turns/list') params.itemsView = 'full'; + const result = await client.request(method, params) as { + data?: unknown[]; + nextCursor?: string | null; + }; if (!Array.isArray(result.data)) break; collected.push(...result.data); if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; @@ -192,43 +303,136 @@ async function readTurnsForId( if (collected.length > 0) { return sliceTurns(normalizeTurns(collected), { limit, full }); } - } catch { - // try next method + } catch (error) { + if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); } } - throw new Error(`app-server has no turn history for thread ${threadId}`); } function sliceTurns( - turns: ReadThreadResult['turns'], + turns: ChatGptDesktopTurn[], { limit, full }: { limit: number; full: boolean }, -): ReadThreadResult['turns'] { +): ChatGptDesktopTurn[] { if (limit <= 0) return turns; if (full) return turns.slice(0, limit); return turns.slice(-limit); } -function normalizeTurns(raw: unknown[]): ReadThreadResult['turns'] { - const turns: Array = []; +function normalizeTurns(raw: unknown[]): ChatGptDesktopTurn[] { + const turns: ChatGptDesktopTurn[] = []; for (const [index, item] of raw.entries()) { if (!item || typeof item !== 'object') continue; const row = item as Record; - const text = - typeof row.text === 'string' - ? row.text - : typeof row.content === 'string' - ? row.content - : ''; - const type = String(row.type ?? row.role ?? ''); - let role: 'user' | 'assistant' | 'status' = 'assistant'; - if (/user/i.test(type)) role = 'user'; - else if (/status|system|reasoning/i.test(type) && !text) role = 'status'; - turns.push({ - turnKey: String(row.id ?? row.turnId ?? index), - role, - text, - }); + const id = String(row.id ?? row.turnId ?? index); + const items = Array.isArray(row.items) ? row.items : null; + if (items) { + turns.push(normalizeTurnWithItems(id, row, items)); + continue; + } + turns.push(normalizeLeafItem(id, row)); } return turns; } + +function normalizeTurnWithItems( + id: string, + row: Record, + items: unknown[], +): ChatGptDesktopTurn { + let userText = ''; + let assistantText = ''; + let toolText = ''; + let reasoningText = ''; + for (const entry of items) { + if (!entry || typeof entry !== 'object') continue; + const item = entry as Record; + const type = String(item.type ?? item.role ?? ''); + const text = extractText(item); + if (/user/i.test(type)) userText = joinText(userText, text); + else if (/agent|assistant|message/i.test(type) && !/reasoning|tool/i.test(type)) { + assistantText = joinText(assistantText, text); + } else if (/tool/i.test(type)) toolText = joinText(toolText, text || type); + else if (/reasoning/i.test(type)) reasoningText = joinText(reasoningText, text); + } + let role: ChatGptDesktopTurn['role'] = 'assistant'; + let text = assistantText || userText; + if (userText && !assistantText) { + role = 'user'; + text = userText; + } else if (!userText && !assistantText && toolText) { + role = 'tool'; + text = toolText; + } else if (!userText && !assistantText && reasoningText) { + role = 'reasoning'; + text = reasoningText; + } + return { + turnKey: toDomTurnKey(id), + role, + text, + ...(userText ? { userText } : {}), + ...(assistantText ? { assistantText } : {}), + startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, + endedAt: typeof row.endedAt === 'number' ? row.endedAt : null, + }; +} + +function normalizeLeafItem(id: string, row: Record): ChatGptDesktopTurn { + const text = extractText(row); + const type = String(row.type ?? row.role ?? ''); + let role: ChatGptDesktopTurn['role'] = 'assistant'; + if (/user/i.test(type)) role = 'user'; + else if (/tool/i.test(type)) role = 'tool'; + else if (/reasoning/i.test(type)) role = 'reasoning'; + else if (/status|system/i.test(type) && !text) role = 'status'; + return { + turnKey: toDomTurnKey(id), + role, + text, + startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, + endedAt: typeof row.endedAt === 'number' ? row.endedAt : null, + }; +} + +function extractText(row: Record): string { + if (typeof row.text === 'string') return row.text; + if (typeof row.content === 'string') return row.content; + if (typeof row.preview === 'string') return row.preview; + return ''; +} + +function joinText(left: string, right: string): string { + if (!right) return left; + if (!left) return right; + return `${left}\n${right}`; +} + +function isThreadNotLoaded(error: unknown): boolean { + const message = errorMessage(error); + return /thread not loaded|not loaded|invalid thread id/i.test(message); +} + +function maybeRemoteThreadError(error: unknown, threadId: string): Error { + const message = errorMessage(error); + if (/thread not loaded|not loaded/i.test(message)) { + const hostId = findRemoteThreadHostId(threadId); + return new RemoteThreadNotLoadedError(threadId, hostId); + } + if (error instanceof Error) return error; + return new Error(message || `app-server error for thread ${threadId}`); +} + +function errorMessage(error: unknown): string { + if (!error) return ''; + if (typeof error === 'string') return error; + if (error instanceof Error) return error.message; + if (typeof error === 'object' && error && 'message' in error) { + return String((error as { message: unknown }).message); + } + if (typeof error === 'object' && error && 'rpc' in error) { + const rpc = (error as { rpc?: { message?: unknown } }).rpc; + if (rpc && typeof rpc.message === 'string') return rpc.message; + } + return String(error); +} diff --git a/src/core/chatgpt-desktop/errors.ts b/src/core/chatgpt-desktop/errors.ts index 55b625a..c657443 100644 --- a/src/core/chatgpt-desktop/errors.ts +++ b/src/core/chatgpt-desktop/errors.ts @@ -40,3 +40,28 @@ export class CdpUnreachableError extends Error { this.name = 'CdpUnreachableError'; } } + +/** + * Thread exists on a remote-control host and is not loaded on the local + * app-server. SSH remoting is a follow-up — this error only names the owner. + */ +export class RemoteThreadNotLoadedError extends Error { + readonly code = 'REMOTE_THREAD_NOT_LOADED' as const; + readonly delivery = 'rejected' as const; + readonly reason = 'remote-thread-not-loaded' as const; + readonly threadId: string; + readonly hostId: string | null; + + constructor(threadId: string, hostId: string | null = null) { + const owner = hostId + ? `owned by remote-control host ${JSON.stringify(hostId)}` + : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + super( + `Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ` + + `${owner}. SSH remoting is not implemented in this adapter yet.`, + ); + this.name = 'RemoteThreadNotLoadedError'; + this.threadId = threadId; + this.hostId = hostId; + } +} diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index 0e952c3..1c3b611 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -2,8 +2,8 @@ import type { ChatGptDesktopAdapter } from './adapter.js'; import { CdpChatGptDesktopAdapter } from './cdp-adapter.js'; import { appServerListThreads, - appServerOpenThread, appServerReadThread, + appServerSearchThreads, appServerStatusProbe, } from './app-server-fallback.js'; import { CdpUnreachableError, NotImplementedError } from './errors.js'; @@ -27,25 +27,24 @@ import type { /** Optional overrides so tests can prove app-server / CDP routing without a live daemon. */ export type ChatGptDesktopFallbacks = { listThreads: typeof appServerListThreads; + searchThreads: typeof appServerSearchThreads; readThread: typeof appServerReadThread; - openThread: typeof appServerOpenThread; statusProbe: typeof appServerStatusProbe; }; const defaultFallbacks: ChatGptDesktopFallbacks = { listThreads: appServerListThreads, + searchThreads: appServerSearchThreads, readThread: appServerReadThread, - openThread: appServerOpenThread, statusProbe: appServerStatusProbe, }; /** - * ChatGPT Desktop facade. + * ChatGPT Desktop facade (verified against app-server 0.158.0). * - * - List: app-server when available; merge CDP-only fields (pinned/selected/project). - * - Read: visible/recent stays on CDP DOM; deep / full-history uses app-server - * (`thread/read` / resume with turns). DOM wheel crawl is last-resort only. - * - Send, new-thread-in-project, wait-for-reply: CDP only. + * - List / search / read: app-server primary (`thread/list`, `thread/read` + + * `thread/turns/list`). DOM read is fallback only when app-server is unavailable. + * - Send, new-thread-in-project, wait-for-reply, selected thread / UI state: CDP. * - Every list/read/send/wait/open result reports `backend: "cdp" | "app-server"`. * * Reuses the existing Codex app-server client — never duplicates that JSON-RPC stack. @@ -107,7 +106,6 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { if (appList && cdpList) { return mergeThreadLists(appList, cdpList); } - // App-server is primary; CDP merge is best-effort (skip NotImplemented / other DOM gaps). if (appList) return appList; if (cdpList) return cdpList; if (cdpError) throw cdpError; @@ -115,6 +113,31 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { throw new CdpUnreachableError('ChatGPT Desktop listThreads: CDP and app-server unreachable'); } + async searchThreads(options: { + query: string; + limit?: number; + }): Promise { + try { + const appList = await this.#fallbacks.searchThreads(options); + const cdpList = await this.#tryCdpList({ limit: options.limit }); + if (cdpList) return mergeThreadLists(appList, cdpList); + return appList; + } catch (appError) { + const cdpList = await this.#tryCdpList({ limit: options.limit }); + if (!cdpList) throw appError; + const needle = options.query.trim().toLowerCase(); + return { + ...cdpList, + query: options.query, + threads: cdpList.threads.filter((thread) => { + if (!needle) return true; + return [thread.title, thread.threadId, thread.project] + .some((value) => typeof value === 'string' && value.toLowerCase().includes(needle)); + }), + }; + } + } + async readThread(options: { threadId: string; limit?: number; @@ -123,42 +146,25 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { }): Promise { const limit = options.limit ?? 100; const full = options.full ?? false; - const cdpConnected = await this.#tryEnsureCdp(); // Temporary sidebar rows have no app-server mapping — CDP only. if (isTemporaryDesktopThreadId(options.threadId)) { - if (!cdpConnected) { - throw new CdpUnreachableError( - `ChatGPT Desktop temporary thread ${options.threadId} requires CDP`, - ); - } + await this.#ensureCdp(); return this.#cdp.readThread({ ...options, limit, full }); } - // Quick visible/recent read via CDP when that is enough. - if (cdpConnected && !full) { - const visible = await this.#cdp.readThread({ ...options, limit, full: false }); - if (limit <= visible.turns.length) { - return visible; - } - // Requested more turns than the DOM shows — escalate to app-server. - } - - // Deep / full-history: app-server first. + // App-server is primary for all durable reads. try { return await this.#fallbacks.readThread({ threadId: options.threadId, limit, - // Preserve caller intent: full=true takes history from the start; - // otherwise return the most recent `limit` turns from full history. full, }); } catch (appError) { - // DOM wheel crawl only when app-server does not know the thread / is unreachable. - if (cdpConnected) { - return this.#cdp.readThread({ ...options, limit, full: true }); - } - throw appError; + // DOM harvest / wheel crawl only when app-server is unavailable. + const cdpConnected = await this.#tryEnsureCdp(); + if (!cdpConnected) throw appError; + return this.#cdp.readThread({ ...options, limit, full: full || true }); } } @@ -184,13 +190,9 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { threadId: string, options?: { openTimeoutMs?: number }, ): Promise { - try { - await this.#ensureCdp(); - return await this.#cdp.openThread(threadId, options); - } catch (error) { - if (!isCdpFailure(error)) throw error; - return this.#fallbacks.openThread(threadId); - } + // Selected-thread / UI focus stays on CDP — do not thread/resume for this. + await this.#ensureCdp(); + return this.#cdp.openThread(threadId, options); } async status(): Promise { @@ -210,7 +212,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable - ? 'CDP unreachable; Codex app-server available for list/deep-read' + ? 'CDP unreachable; Codex app-server available for list/search/read' : cdpStatus.message, exitCode: reachable ? 0 : 1, }; @@ -237,9 +239,22 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { return false; } } + + async #tryCdpList(options?: { limit?: number }): Promise { + try { + await this.#ensureCdp(); + return await this.#cdp.listThreads(options); + } catch (error) { + if (isCdpFailure(error) || error instanceof NotImplementedError) { + if (isCdpFailure(error)) this.#cdpConnected = false; + return null; + } + throw error; + } + } } -/** Merge app-server thread inventory with CDP-only sidebar fields. */ +/** Merge app-server thread inventory with CDP-only sidebar fields (selected, etc.). */ export function mergeThreadLists( appList: ListThreadsResult, cdpList: ListThreadsResult, @@ -257,10 +272,10 @@ export function mergeThreadLists( return { ...thread, title: thread.title || cdp.title, - pinned: cdp.pinned, + pinned: thread.pinned || cdp.pinned, selected: cdp.selected, kind: cdp.kind || thread.kind, - ...(cdp.project !== undefined ? { project: cdp.project } : {}), + project: cdp.project ?? thread.project, }; }); @@ -273,6 +288,8 @@ export function mergeThreadLists( return { backend: 'app-server', limit: appList.limit, + nextCursor: appList.nextCursor, + ...(appList.query !== undefined ? { query: appList.query } : {}), threads: merged.slice(0, appList.limit), }; } diff --git a/src/core/chatgpt-desktop/index.ts b/src/core/chatgpt-desktop/index.ts index 0e1efee..bb2bc87 100644 --- a/src/core/chatgpt-desktop/index.ts +++ b/src/core/chatgpt-desktop/index.ts @@ -23,6 +23,7 @@ export { CdpHostRejectedError, CdpUnreachableError, NotImplementedError, + RemoteThreadNotLoadedError, } from './errors.js'; export { ChatGptDesktopFacade, @@ -32,13 +33,20 @@ export { } from './facade.js'; export type { ChatGptDesktopFallbacks } from './facade.js'; export { + HISTORY_CONTENT_TURN_PREFIX, LOCAL_THREAD_ID_PREFIX, appServerThreadIdCandidates, isTemporaryDesktopThreadId, + requireAppServerThreadId, threadIdsEquivalent, toAppServerThreadId, toDesktopThreadId, + toDomTurnKey, } from './thread-ids.js'; +export { + codexGlobalStatePath, + findRemoteThreadHostId, +} from './remote-threads.js'; export { CDP_LOOPBACK_HOST, DEFAULT_CDP_PORT, @@ -62,6 +70,8 @@ export { readThreadSchema, resultSchema, resultText, + searchThreadsOperation, + searchThreadsSchema, sendOperation, sendSchema, statusOperation, @@ -74,6 +84,7 @@ export type { ChatGptDesktopStatus, ChatGptDesktopTarget, ChatGptDesktopThread, + ChatGptDesktopThreadSection, ChatGptDesktopTurn, ListThreadsResult, OpenThreadResult, diff --git a/src/core/chatgpt-desktop/remote-threads.ts b/src/core/chatgpt-desktop/remote-threads.ts new file mode 100644 index 0000000..d347824 --- /dev/null +++ b/src/core/chatgpt-desktop/remote-threads.ts @@ -0,0 +1,75 @@ +/** + * Look up which remote-control host owns a Codex thread that is not loaded + * locally. Reads `~/.codex/.codex-global-state.json` keys shaped like + * `remote-thread-summaries-v3:`. SSH remoting is intentionally not + * implemented here — follow-up work. + */ + +import { readFileSync } from 'node:fs'; +import { homedir } from 'node:os'; +import { join } from 'node:path'; + +import { toAppServerThreadId } from './thread-ids.js'; + +const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; + +export function codexGlobalStatePath(env: NodeJS.ProcessEnv = process.env): string { + const home = env.CODEX_HOME || join(homedir(), '.codex'); + return join(home, '.codex-global-state.json'); +} + +/** Best-effort hostId for a thread listed under a remote-control summary. */ +export function findRemoteThreadHostId( + threadId: string, + env: NodeJS.ProcessEnv = process.env, +): string | null { + const bare = toAppServerThreadId(threadId) ?? threadId; + if (!bare) return null; + let raw: string; + try { + raw = readFileSync(codexGlobalStatePath(env), 'utf8'); + } catch { + return null; + } + let data: unknown; + try { + data = JSON.parse(raw); + } catch { + return null; + } + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + for (const [key, value] of Object.entries(data as Record)) { + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match) continue; + if (summariesIncludeThread(value, bare)) return match[1] ?? null; + } + return null; +} + +function summariesIncludeThread(value: unknown, threadId: string): boolean { + if (Array.isArray(value)) { + return value.some((entry) => entryMentionsThread(entry, threadId)); + } + if (value && typeof value === 'object') { + const record = value as Record; + if (threadId in record) return true; + if (Array.isArray(record.threads)) { + return record.threads.some((entry) => entryMentionsThread(entry, threadId)); + } + if (Array.isArray(record.summaries)) { + return record.summaries.some((entry) => entryMentionsThread(entry, threadId)); + } + return Object.values(record).some((entry) => entryMentionsThread(entry, threadId)); + } + return false; +} + +function entryMentionsThread(entry: unknown, threadId: string): boolean { + if (typeof entry === 'string') return entry === threadId; + if (!entry || typeof entry !== 'object') return false; + const row = entry as Record; + for (const key of ['id', 'threadId', 'thread_id', 'conversationId']) { + if (row[key] === threadId) return true; + } + return false; +} diff --git a/src/core/chatgpt-desktop/routes.ts b/src/core/chatgpt-desktop/routes.ts index de641c6..b5514f5 100644 --- a/src/core/chatgpt-desktop/routes.ts +++ b/src/core/chatgpt-desktop/routes.ts @@ -1,7 +1,7 @@ import { z } from 'zod'; import { outcomeFromError } from '../codex/contract.js'; -import { NotImplementedError } from './errors.js'; +import { NotImplementedError, RemoteThreadNotLoadedError } from './errors.js'; import { getChatGptDesktopAdapter } from './facade.js'; import { resolveCdpPort } from './loopback.js'; @@ -20,6 +20,14 @@ export const listThreadsSchema = z }) .strict(); +export const searchThreadsSchema = z + .object({ + port: z.number().int().min(1).max(65535).optional(), + query: z.string().min(1).max(512), + limit: z.number().int().min(1).max(200).default(50), + }) + .strict(); + export const readThreadSchema = z .object({ port: z.number().int().min(1).max(65535).optional(), @@ -65,7 +73,7 @@ async function withAdapter( try { await adapter.connect({ port: resolved }); } catch { - // status/list may still succeed via HTTP probe or app-server list/deep-read. + // status/list/search/read may still succeed via HTTP probe or app-server. } return run(adapter); } @@ -87,6 +95,17 @@ function mapError(error: unknown): OperationResult { exitCode: 1 as const, }); } + if (error instanceof RemoteThreadNotLoadedError) { + return asResult({ + delivery: error.delivery, + reason: error.reason, + code: error.code, + error: error.message, + threadId: error.threadId, + ...(error.hostId ? { hostId: error.hostId } : {}), + exitCode: 1 as const, + }); + } const base = outcomeFromError(error); if (error && typeof error === 'object' && 'code' in error) { return asResult({ ...base, code: String((error as { code: unknown }).code) }); @@ -116,6 +135,22 @@ export async function listThreadsOperation( } } +export async function searchThreadsOperation( + input: z.infer, +): Promise { + try { + const out = await withAdapter(input.port, async (adapter) => { + if (typeof adapter.searchThreads !== 'function') { + throw new NotImplementedError('searchThreads', 'adapter does not implement search'); + } + return adapter.searchThreads({ query: input.query, limit: input.limit }); + }); + return asResult({ ...out, exitCode: 0 as const }); + } catch (error) { + return mapError(error); + } +} + export async function readThreadOperation( input: z.infer, ): Promise { @@ -179,10 +214,11 @@ export function resultText(result: OperationResult): string { } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); if (Array.isArray(result.threads)) { - return `${result.threads.length} threads via ${result.backend ?? 'unknown'}`; + const via = result.query ? ` matching ${JSON.stringify(result.query)}` : ''; + return `${result.threads.length} threads${via} via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { - const mode = result.full ? 'full' : 'visible'; + const mode = result.full ? 'full' : 'page'; return `${result.turns.length} turns (${mode}) on ${result.threadId} via ${result.backend ?? 'unknown'}`; } if (result.delivery === 'accepted') { diff --git a/src/core/chatgpt-desktop/thread-ids.ts b/src/core/chatgpt-desktop/thread-ids.ts index 9495886..30b85cd 100644 --- a/src/core/chatgpt-desktop/thread-ids.ts +++ b/src/core/chatgpt-desktop/thread-ids.ts @@ -2,8 +2,8 @@ * Desktop sidebar thread ids ↔ Codex app-server thread ids. * * ChatGPT Desktop sidebar rows use `data-app-action-sidebar-thread-id` values - * shaped like `local:`. The Codex app-server `thread/list`, - * `thread/read`, and `thread/resume` APIs use the bare ``. + * shaped like `local:`. App-server APIs use the bare + * `` only — the `local:` form fails with `invalid thread id`. * * Temporary composer rows (`local:client-new-thread:…`) are CDP-only until the * first reply annotates a real conversation id — they do not map to app-server. @@ -13,13 +13,16 @@ import { TEMP_THREAD_ID_PREFIX } from './cdp-dom.js'; export const LOCAL_THREAD_ID_PREFIX = 'local:' as const; +/** DOM `data-turn-key` prefix; app-server turn ids are the trailing segment. */ +export const HISTORY_CONTENT_TURN_PREFIX = 'history-content:turn:' as const; + /** True when the id is a transient sidebar row, not a durable conversation. */ export function isTemporaryDesktopThreadId(threadId: string): boolean { return threadId.startsWith(TEMP_THREAD_ID_PREFIX); } /** - * Map a Desktop sidebar id to the app-server thread id. + * Map a Desktop sidebar id (or bare id) to the app-server thread id. * Returns null when the id is temporary or empty (no app-server mapping). */ export function toAppServerThreadId(threadId: string): string | null { @@ -31,6 +34,18 @@ export function toAppServerThreadId(threadId: string): string | null { return threadId; } +/** Require a bare app-server id; throws when the input cannot be mapped. */ +export function requireAppServerThreadId(threadId: string): string { + const bare = toAppServerThreadId(threadId); + if (!bare) { + throw new Error( + `No app-server thread id mapping for ${JSON.stringify(threadId)} ` + + `(temporary Desktop rows need CDP; strip a leading "local:" for durable ids)`, + ); + } + return bare; +} + /** Present an app-server (or bare) id in Desktop sidebar form. */ export function toDesktopThreadId(threadId: string): string { if (!threadId || isTemporaryDesktopThreadId(threadId)) return threadId; @@ -45,19 +60,18 @@ export function threadIdsEquivalent(a: string, b: string): boolean { return left === right; } +/** Format an app-server turn id as the DOM `data-turn-key` value. */ +export function toDomTurnKey(turnId: string): string { + if (!turnId) return turnId; + if (turnId.startsWith(HISTORY_CONTENT_TURN_PREFIX)) return turnId; + return `${HISTORY_CONTENT_TURN_PREFIX}${turnId}`; +} + /** - * Ordered candidates to try against app-server. Prefer the bare conversation - * id; also try the original and `local:` form so mapping can be verified. + * @deprecated Prefer requireAppServerThreadId — the `local:` form is rejected + * by app-server (`invalid thread id`). Kept for callers that want a list. */ export function appServerThreadIdCandidates(threadId: string): string[] { - if (!threadId || isTemporaryDesktopThreadId(threadId)) return []; const bare = toAppServerThreadId(threadId); - const out: string[] = []; - const push = (id: string | null | undefined) => { - if (id && !out.includes(id)) out.push(id); - }; - push(bare); - push(threadId); - if (bare) push(toDesktopThreadId(bare)); - return out; + return bare ? [bare] : []; } diff --git a/src/core/chatgpt-desktop/types.ts b/src/core/chatgpt-desktop/types.ts index d07da12..718d7b7 100644 --- a/src/core/chatgpt-desktop/types.ts +++ b/src/core/chatgpt-desktop/types.ts @@ -8,24 +8,43 @@ export type ChatGptDesktopTarget = { readonly attached: boolean; }; +export type ChatGptDesktopThreadSection = { + readonly id: string; + readonly name: string | null; +}; + export type ChatGptDesktopThread = { readonly threadId: string; readonly title: string; readonly pinned: boolean; + /** CDP-only: currently selected sidebar row. */ readonly selected: boolean; readonly kind: string; - /** CDP-only: project folder from the sidebar when known. */ + /** Project folder name when known (CDP sidebar or app-server projectId). */ readonly project?: string; + readonly preview?: string; + readonly cwd?: string | null; + readonly createdAt?: number | null; + readonly updatedAt?: number | null; + readonly section?: ChatGptDesktopThreadSection | null; + readonly projectId?: string | null; + readonly status?: string; + readonly modelProvider?: string | null; + readonly model?: string | null; + readonly originator?: string | null; }; export type ChatGptDesktopTurn = { + /** Prefer DOM form `history-content:turn:` when the bare turn id is known. */ readonly turnKey: string; - readonly role: 'user' | 'assistant' | 'status'; + readonly role: 'user' | 'assistant' | 'status' | 'tool' | 'reasoning'; readonly text: string; /** User bubble text when the turn holds both sides. */ readonly userText?: string; /** Final assistant markdown when present on the same turn. */ readonly assistantText?: string; + readonly startedAt?: number | null; + readonly endedAt?: number | null; }; export type ChatGptDesktopStatus = { @@ -50,6 +69,8 @@ export type ListThreadsResult = { readonly threads: readonly ChatGptDesktopThread[]; readonly backend: ChatGptDesktopBackend; readonly limit: number; + readonly nextCursor?: string | null; + readonly query?: string; }; export type ReadThreadResult = { @@ -58,6 +79,11 @@ export type ReadThreadResult = { readonly backend: ChatGptDesktopBackend; readonly limit: number; readonly full: boolean; + readonly title?: string; + readonly cwd?: string | null; + readonly status?: string; + readonly modelProvider?: string | null; + readonly model?: string | null; }; export type SendMessageResult = { diff --git a/src/core/codex-bridge.js b/src/core/codex-bridge.js index 04cfe5e..594d522 100644 --- a/src/core/codex-bridge.js +++ b/src/core/codex-bridge.js @@ -827,6 +827,14 @@ function sourceField(value) { return typeof value === "string" ? singleLine(value) : value; } +function summarizeSection(section) { + if (!isObject(section) || typeof section.id !== "string" || !section.id) return null; + return { + id: singleLine(section.id), + name: lineField(section.name), + }; +} + function summarizeThread(t) { if (!isObject(t) || typeof t.id !== "string" || !t.id) throw new CodexProtocolError("thread/list", "entry without a string `id`"); const type = isObject(t.status) && typeof t.status.type === "string" ? t.status.type : "unknown"; @@ -838,7 +846,13 @@ function summarizeThread(t) { preview: typeof t.preview === "string" ? stripTerminalControls(t.preview) : "", cwd: lineField(t.cwd), source: sourceField(t.source), + createdAt: typeof t.createdAt === "number" ? t.createdAt : null, updatedAt: typeof t.updatedAt === "number" ? t.updatedAt : null, + section: summarizeSection(t.section), + projectId: lineField(t.projectId), + modelProvider: lineField(t.modelProvider), + model: lineField(t.model), + originator: lineField(t.originator), }; } @@ -854,9 +868,15 @@ export async function listCodexThreads({ limit = 20, cursor, env = process.env } if (cursor !== undefined && (typeof cursor !== "string" || !cursor)) throw new RangeError("--cursor must be a non-empty string"); const { client } = await openSession(env); try { - // The default listing rescans every rollout file to repair metadata (26 s on a busy machine); - // the state DB already holds what we print. - const params = { limit, useStateDbOnly: true, ...(cursor !== undefined ? { cursor } : {}) }; + // Default thread/list filters to the current model provider and misses other + // providers' threads. Pass modelProviders: [] for the full inventory. + // useStateDbOnly avoids a cold rollout rescan (tens of seconds). + const params = { + limit, + useStateDbOnly: true, + modelProviders: [], + ...(cursor !== undefined ? { cursor } : {}), + }; let out; try { out = await client.request("thread/list", params); diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx index f174ad4..44e006d 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list threads', description: - 'List ChatGPT Desktop threads via the Codex app-server when available (thread/list), merging CDP-only sidebar fields (pinned, selected, project, kind) when CDP is connected. Desktop local: maps to bare app-server ids. Result includes backend.', + 'List ChatGPT Desktop / Codex threads via app-server thread/list (modelProviders:[], useStateDbOnly). Merges CDP-only UI fields (selected, pinned overlay) when CDP is connected. Desktop local: strips to bare app-server ids. Result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx index b5f2925..f736690 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop read thread', description: - 'Read a ChatGPT Desktop thread. Visible/recent turns use local CDP DOM harvest. full=true or a limit above the on-screen turns uses the Codex app-server (thread/read / resume); Desktop local: maps to the bare app-server id. DOM wheel crawl is only a fallback when app-server misses the thread. Result includes backend.', + 'Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. DOM harvest/wheel is fallback only when app-server is unavailable. Result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -32,7 +32,7 @@ export default defineTool( full: { type: 'boolean', description: - 'When true, read full history via app-server (CDP wheel only if app-server unavailable). Default false = visible CDP turns when that satisfies limit.', + 'When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.', }, openTimeoutMs: { type: 'number', diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx new file mode 100644 index 0000000..74be9c0 --- /dev/null +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx @@ -0,0 +1,39 @@ +import { Agent } from '@agent-bundle/runtime'; +import { defineTool } from 'agent-bundle/routes'; +import { + resultSchema, + resultText, + searchThreadsOperation, + searchThreadsSchema as inputSchema, +} from '../../../core/chatgpt-desktop/routes.js'; + +export { inputSchema }; + +export default defineTool( + { + title: 'ChatGPT Desktop search threads', + description: + 'Search ChatGPT Desktop / Codex threads through the local app-server (thread/list with modelProviders:[]), matching name/preview/cwd/project/model fields. Merges CDP selected/pinned when connected. Result includes backend.', + annotations: { readOnlyHint: true }, + inputSchema, + resultSchema, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { type: 'number' }, + query: { type: 'string', description: 'Case-insensitive substring over thread metadata.' }, + limit: { type: 'number', description: 'Maximum matches (1-200).' }, + }, + required: ['query'], + }, + }, + async (input) => { + const out = await searchThreadsOperation(input); + return ( + + {resultText(out)} + + ); + }, +); diff --git a/test/codex-bridge.test.js b/test/codex-bridge.test.js index d83dc1d..7aa0b22 100644 --- a/test/codex-bridge.test.js +++ b/test/codex-bridge.test.js @@ -103,20 +103,109 @@ test("codex list-threads passes --limit and prints threads", async () => { const text = await gbot(fake.home, "codex", "list-threads", "--limit", "1"); assert.equal(text.code, 0, text.err); assert.equal(text.out, "t-1 idle - Fix the build\n /repo/a\n please fix the build\n\nmore: --cursor \"cursor-2\"\n"); - assert.deepEqual(fake.received.find((m) => m.method === "thread/list").params, { limit: 1, useStateDbOnly: true }); + assert.deepEqual(fake.received.find((m) => m.method === "thread/list").params, { + limit: 1, + useStateDbOnly: true, + modelProviders: [], + }); const json = await gbot(fake.home, "codex", "list-threads", "--json"); assert.equal(json.code, 0, json.err); assert.deepEqual(JSON.parse(json.out), { threads: [ - { id: "t-1", status: "idle", activeFlags: [], name: "Fix the build", preview: "please fix the build", cwd: "/repo/a", source: "vscode", updatedAt: 1700000001 }, - { id: "t-2", status: "notLoaded", activeFlags: [], name: null, preview: "second thread\npreview", cwd: "/repo/b", source: "cli", updatedAt: 1700000000 }, + { + id: "t-1", + status: "idle", + activeFlags: [], + name: "Fix the build", + preview: "please fix the build", + cwd: "/repo/a", + source: "vscode", + createdAt: null, + updatedAt: 1700000001, + section: null, + projectId: null, + modelProvider: null, + model: null, + originator: null, + }, + { + id: "t-2", + status: "notLoaded", + activeFlags: [], + name: null, + preview: "second thread\npreview", + cwd: "/repo/b", + source: "cli", + createdAt: null, + updatedAt: 1700000000, + section: null, + projectId: null, + modelProvider: null, + model: null, + originator: null, + }, ], nextCursor: null, limit: 20, exitCode: 0, }); - assert.deepEqual(fake.received.at(-1).params, { limit: 20, useStateDbOnly: true }); + assert.deepEqual(fake.received.at(-1).params, { + limit: 20, + useStateDbOnly: true, + modelProviders: [], + }); + } finally { + await fake.close(); + } +}); + +test("codex list-threads passes modelProviders:[] so other providers are not filtered out", async () => { + const seen = []; + const fake = await fakeAppServer({ + ...baseHandlers, + "thread/list": (params, ok) => { + seen.push(params); + ok({ + data: [ + { + id: "openai-1", + status: { type: "idle" }, + name: "OpenAI thread", + preview: "a", + cwd: "/a", + modelProvider: "openai", + updatedAt: 1, + }, + { + id: "other-1", + status: { type: "idle" }, + name: "Other provider", + preview: "b", + cwd: "/b", + modelProvider: "azure", + section: { id: "Pinned", name: "Pinned" }, + projectId: "proj-1", + model: "gpt-x", + originator: "desktop", + createdAt: 10, + updatedAt: 20, + }, + ], + nextCursor: null, + }); + }, + }); + try { + const { code, out } = await gbot(fake.home, "codex", "list-threads", "--json"); + assert.equal(code, 0, out); + assert.deepEqual(seen[0], { limit: 20, useStateDbOnly: true, modelProviders: [] }); + const page = JSON.parse(out); + assert.deepEqual(page.threads.map((t) => t.id), ["openai-1", "other-1"]); + assert.equal(page.threads[1].modelProvider, "azure"); + assert.deepEqual(page.threads[1].section, { id: "Pinned", name: "Pinned" }); + assert.equal(page.threads[1].projectId, "proj-1"); + assert.equal(page.threads[1].createdAt, 10); } finally { await fake.close(); } @@ -792,7 +881,7 @@ test("codex list-threads pages with --cursor, echoes nextCursor, and rejects unk const second = await gbot(fake.home, "codex", "list-threads", "--limit", "1", "--cursor", "page-2", "--json"); assert.deepEqual(JSON.parse(second.out).threads.map((t) => t.id), ["t-2"]); assert.equal(JSON.parse(second.out).nextCursor, null); - assert.deepEqual(seen.at(-1), { limit: 1, useStateDbOnly: true, cursor: "page-2" }); + assert.deepEqual(seen.at(-1), { limit: 1, useStateDbOnly: true, modelProviders: [], cursor: "page-2" }); const unknown = await gbot(fake.home, "codex", "list-threads", "--all"); assert.equal(unknown.code, 2); @@ -835,8 +924,38 @@ test("codex list-threads sanitizes text fields, keeps structured source, and rej assert.equal(code, 0); const { threads } = JSON.parse(out); assert.deepEqual(threads, [ - { id: "t-x line", status: "active", activeFlags: ["waitingOnApproval"], name: "a b", preview: "keep\nnewlines", cwd: "/r", source: { custom: "hauler\u001b[0m" }, updatedAt: null }, - { id: "t-odd", status: "unknown", activeFlags: [], name: null, preview: "", cwd: null, source: "cli", updatedAt: null }, + { + id: "t-x line", + status: "active", + activeFlags: ["waitingOnApproval"], + name: "a b", + preview: "keep\nnewlines", + cwd: "/r", + source: { custom: "hauler\u001b[0m" }, + createdAt: null, + updatedAt: null, + section: null, + projectId: null, + modelProvider: null, + model: null, + originator: null, + }, + { + id: "t-odd", + status: "unknown", + activeFlags: [], + name: null, + preview: "", + cwd: null, + source: "cli", + createdAt: null, + updatedAt: null, + section: null, + projectId: null, + modelProvider: null, + model: null, + originator: null, + }, ]); } finally { await fake.close(); diff --git a/test/host-tool-inventory.test.js b/test/host-tool-inventory.test.js index 075c462..44b82c2 100644 --- a/test/host-tool-inventory.test.js +++ b/test/host-tool-inventory.test.js @@ -14,6 +14,7 @@ const grok = ['gbot_send', 'gbot_thread', 'gbot_grok_approvals', 'gbot_grok_resp const shared = [ 'chatgpt_desktop_list_threads', 'chatgpt_desktop_read_thread', + 'chatgpt_desktop_search_threads', 'chatgpt_desktop_send', 'chatgpt_desktop_status', 'chatgpt_desktop_wait_reply', diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index 8a814cd..de602a2 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -19,6 +19,7 @@ import { ChatGptDesktopFacade } from '../../src/core/chatgpt-desktop/facade.js'; const desktopTools = [ 'chatgpt_desktop_list_threads', 'chatgpt_desktop_read_thread', + 'chatgpt_desktop_search_threads', 'chatgpt_desktop_send', 'chatgpt_desktop_status', 'chatgpt_desktop_wait_reply', @@ -188,6 +189,7 @@ describe('chatgpt-desktop thread id mapping', () => { threadIdsEquivalent, toAppServerThreadId, toDesktopThreadId, + toDomTurnKey, } = await import('../../src/core/chatgpt-desktop/index.js'); const bare = '11111111-1111-1111-1111-111111111111'; @@ -198,7 +200,9 @@ describe('chatgpt-desktop thread id mapping', () => { expect(toDesktopThreadId(local)).toBe(local); expect(threadIdsEquivalent(local, bare)).toBe(true); expect(appServerThreadIdCandidates(local)[0]).toBe(bare); - expect(appServerThreadIdCandidates(local)).toContain(local); + expect(appServerThreadIdCandidates(local)).toEqual([bare]); + expect(toDomTurnKey('abc')).toBe('history-content:turn:abc'); + expect(toDomTurnKey('history-content:turn:abc')).toBe('history-content:turn:abc'); const temp = `${TEMP_THREAD_ID_PREFIX}deadbeef`; expect(isTemporaryDesktopThreadId(temp)).toBe(true); @@ -258,7 +262,7 @@ describe('chatgpt-desktop thread id mapping', () => { }); describe('chatgpt-desktop MCP tools', () => { - it('registers the five chatgpt_desktop_* tools on the grok-bot server', async () => { + it('registers the chatgpt_desktop_* tools on the grok-bot server', async () => { const surface = await listMcpSurface({ server: 'grok-bot' }); for (const name of desktopTools) { expect(surface.tools.includes(name)).toBe(true); @@ -411,8 +415,60 @@ describe('chatgpt-desktop CLI', () => { }); }); -describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => { - it('lists via app-server (merged with CDP), deep-reads via app-server, keeps send/wait on CDP', async () => { +describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () => { + const appFallbacks = (calls: string[]) => ({ + listThreads: async ({ limit = 50 } = {}) => { + calls.push('app-server.listThreads'); + return { + backend: 'app-server' as const, + limit, + threads: [ + { + threadId: 'local:11111111-1111-1111-1111-111111111111', + title: 'from app-server', + pinned: false, + selected: false, + kind: 'codex', + section: { id: 'Pinned', name: 'Pinned' }, + modelProvider: 'openai', + }, + ], + }; + }, + searchThreads: async ({ query, limit = 50 }: { query: string; limit?: number }) => { + calls.push('app-server.searchThreads'); + return { + backend: 'app-server' as const, + limit, + query, + threads: [ + { + threadId: 'local:11111111-1111-1111-1111-111111111111', + title: 'from app-server', + pinned: true, + selected: false, + kind: 'codex', + }, + ], + }; + }, + readThread: async ({ threadId, limit = 100, full = false }: { threadId: string; limit?: number; full?: boolean }) => { + calls.push('app-server.readThread'); + return { + threadId, + backend: 'app-server' as const, + limit, + full, + turns: [ + { turnKey: 'history-content:turn:t1', role: 'user' as const, text: 'hello' }, + { turnKey: 'history-content:turn:t2', role: 'assistant' as const, text: 'deep history' }, + ], + }; + }, + statusProbe: async () => ({ reachable: true, mode: 'daemon', socketPath: '/tmp/fake.sock' }), + }); + + it('lists/searches/reads via app-server (merged with CDP), keeps send/wait/open on CDP', async () => { const calls: string[] = []; const cdp = fakeAdapter({ async connect() { @@ -442,12 +498,7 @@ describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => backend: 'cdp', limit, full, - turns: full - ? [ - { turnKey: 'old', role: 'user' as const, text: 'wheel' }, - { turnKey: 'new', role: 'assistant' as const, text: 'wheel-reply' }, - ] - : [{ turnKey: 'visible', role: 'assistant' as const, text: 'on screen' }], + turns: [{ turnKey: 'visible', role: 'assistant' as const, text: 'on screen' }], }; }, async sendMessage({ threadId, text }) { @@ -470,6 +521,10 @@ describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => delivery: 'replied' as const, }; }, + async openThread(threadId) { + calls.push('cdp.openThread'); + return { threadId, backend: 'cdp' as const }; + }, async status() { return { reachable: true, @@ -481,39 +536,7 @@ describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => }, }); - const facade = new ChatGptDesktopFacade(cdp, 9222, { - listThreads: async ({ limit = 50 } = {}) => { - calls.push('app-server.listThreads'); - return { - backend: 'app-server', - limit, - threads: [ - { - threadId: 'local:11111111-1111-1111-1111-111111111111', - title: 'from app-server', - pinned: false, - selected: false, - kind: 'codex', - }, - ], - }; - }, - readThread: async ({ threadId, limit = 100, full = false }) => { - calls.push('app-server.readThread'); - return { - threadId, - backend: 'app-server', - limit, - full, - turns: [ - { turnKey: 't1', role: 'user', text: 'hello' }, - { turnKey: 't2', role: 'assistant', text: 'deep history' }, - ], - }; - }, - openThread: async (threadId) => ({ threadId, backend: 'app-server' as const }), - statusProbe: async () => ({ reachable: true, mode: 'daemon', socketPath: '/tmp/fake.sock' }), - }); + const facade = new ChatGptDesktopFacade(cdp, 9222, appFallbacks(calls)); const listed = await facade.listThreads({ limit: 5 }); expect(listed).toMatchObject({ @@ -522,54 +545,62 @@ describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => { threadId: 'local:11111111-1111-1111-1111-111111111111', title: 'from app-server', - pinned: true, selected: true, project: 'Launch', }, ], }); - // limit 100 > one visible turn → escalate to app-server + const searched = await facade.searchThreads({ query: 'app-server', limit: 5 }); + expect(searched).toMatchObject({ + backend: 'app-server', + query: 'app-server', + threads: [{ selected: true, project: 'Launch' }], + }); + + // App-server is primary for every durable read (no visible-first CDP hop). const deep = await facade.readThread({ threadId: 'local:11111111-1111-1111-1111-111111111111', limit: 100, }); - expect(deep).toMatchObject({ backend: 'app-server', turns: [{ text: 'hello' }, { text: 'deep history' }] }); + expect(deep).toMatchObject({ + backend: 'app-server', + turns: [ + { turnKey: 'history-content:turn:t1', text: 'hello' }, + { turnKey: 'history-content:turn:t2', text: 'deep history' }, + ], + }); - // full=true → app-server without requiring a visible undershoot const full = await facade.readThread({ threadId: 'local:11111111-1111-1111-1111-111111111111', full: true, }); expect(full.backend).toBe('app-server'); - // small limit satisfied by visible CDP harvest - const visible = await facade.readThread({ - threadId: 'local:11111111-1111-1111-1111-111111111111', - limit: 1, - }); - expect(visible).toMatchObject({ backend: 'cdp', turns: [{ text: 'on screen' }] }); - const sent = await facade.sendMessage({ threadId: 'local:11111111-1111-1111-1111-111111111111', text: 'hi' }); expect(sent).toMatchObject({ backend: 'cdp', delivery: 'accepted' }); const waited = await facade.waitForReply({ threadId: 'local:11111111-1111-1111-1111-111111111111' }); expect(waited).toMatchObject({ backend: 'cdp', delivery: 'replied' }); + const opened = await facade.openThread('local:11111111-1111-1111-1111-111111111111'); + expect(opened).toMatchObject({ backend: 'cdp' }); + expect(calls).toEqual([ 'app-server.listThreads', 'cdp.connect', 'cdp.listThreads', - 'cdp.readThread:visible', + 'app-server.searchThreads', + 'cdp.listThreads', 'app-server.readThread', 'app-server.readThread', - 'cdp.readThread:visible', 'cdp.sendMessage', 'cdp.waitForReply', + 'cdp.openThread', ]); }); - it('falls back to CDP wheel crawl when app-server deep-read fails', async () => { + it('falls back to CDP read when app-server is unavailable', async () => { const calls: string[] = []; const facade = new ChatGptDesktopFacade( fakeAdapter({ @@ -590,13 +621,11 @@ describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => 9222, { listThreads: async () => ({ backend: 'app-server', limit: 1, threads: [] }), + searchThreads: async () => ({ backend: 'app-server', limit: 1, query: '', threads: [] }), readThread: async () => { calls.push('app-server.readThread'); throw new Error('unknown thread'); }, - openThread: async () => { - throw new Error('unused'); - }, statusProbe: async () => ({ reachable: false }), }, ); @@ -606,7 +635,7 @@ describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => full: true, }); expect(read).toMatchObject({ backend: 'cdp', turns: [{ text: 'from wheel' }] }); - expect(calls).toEqual(['cdp.connect', 'app-server.readThread', 'cdp.readThread:full']); + expect(calls).toEqual(['app-server.readThread', 'cdp.connect', 'cdp.readThread:full']); }); it('does not fall back send/wait to app-server when CDP is down', async () => { @@ -647,6 +676,12 @@ describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => }, ], }), + searchThreads: async ({ query, limit = 50 }) => ({ + backend: 'app-server', + limit, + query, + threads: [], + }), readThread: async ({ threadId, limit = 100, full = false }) => ({ threadId, backend: 'app-server', @@ -654,7 +689,6 @@ describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => full, turns: [{ turnKey: 't1', role: 'assistant', text: 'fallback reply' }], }), - openThread: async (threadId) => ({ threadId, backend: 'app-server' as const }), statusProbe: async () => ({ reachable: true, mode: 'daemon', socketPath: '/tmp/fake.sock' }), }, ); @@ -676,7 +710,7 @@ describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => expect(status).toMatchObject({ reachable: true, appServerFallback: { reachable: true, mode: 'daemon' }, - message: 'CDP unreachable; Codex app-server available for list/deep-read', + message: 'CDP unreachable; Codex app-server available for list/search/read', exitCode: 0, }); }); @@ -704,12 +738,10 @@ describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => }, ], }), + searchThreads: async () => ({ backend: 'app-server', limit: 1, query: '', threads: [] }), readThread: async () => { throw new Error('unused'); }, - openThread: async () => { - throw new Error('unused'); - }, statusProbe: async () => ({ reachable: false }), }, ); @@ -719,6 +751,28 @@ describe('chatgpt-desktop app-server list/deep-read + CDP-only send/wait', () => threads: [{ threadId: 'local:codex-1' }], }); }); + + it('surfaces RemoteThreadNotLoadedError with hostId from global state', async () => { + const { mkdtempSync, writeFileSync } = await import('node:fs'); + const { tmpdir } = await import('node:os'); + const { join } = await import('node:path'); + const { RemoteThreadNotLoadedError, findRemoteThreadHostId } = await import( + '../../src/core/chatgpt-desktop/index.js' + ); + const home = mkdtempSync(join(tmpdir(), 'gbot-remote-')); + writeFileSync( + join(home, '.codex-global-state.json'), + JSON.stringify({ + 'remote-thread-summaries-v3:host-abc': [{ id: 'remote-thread-1' }], + }), + ); + expect(findRemoteThreadHostId('remote-thread-1', { CODEX_HOME: home })).toBe('host-abc'); + expect(findRemoteThreadHostId('local:remote-thread-1', { CODEX_HOME: home })).toBe('host-abc'); + const err = new RemoteThreadNotLoadedError('remote-thread-1', 'host-abc'); + expect(err.code).toBe('REMOTE_THREAD_NOT_LOADED'); + expect(err.hostId).toBe('host-abc'); + expect(err.message).toMatch(/host-abc/); + }); }); describe('chatgpt-desktop CDP HTTP status probe', () => { diff --git a/tests/route-unit/tools.test.ts b/tests/route-unit/tools.test.ts index f21d77e..260ce35 100644 --- a/tests/route-unit/tools.test.ts +++ b/tests/route-unit/tools.test.ts @@ -133,7 +133,7 @@ beforeEach(() => { describe('grok-bot MCP server', () => { it('registers messaging, conversation and managed bridge tools', async () => { const surface = await listMcpSurface({ server: 'grok-bot' }); - expect([...surface.tools].sort()).toEqual(['chatgpt_desktop_list_threads', 'chatgpt_desktop_read_thread', 'chatgpt_desktop_send', 'chatgpt_desktop_status', 'chatgpt_desktop_wait_reply', 'claude_send', 'codex_send', 'codex_threads', 'codex_wait', 'codex_watch', 'gbot_bridge_start', 'gbot_bridge_status', 'gbot_bridge_stop', 'gbot_codex_respond', 'gbot_grok_approvals', 'gbot_grok_respond', 'gbot_send', 'gbot_thread']); + expect([...surface.tools].sort()).toEqual(['chatgpt_desktop_list_threads', 'chatgpt_desktop_read_thread', 'chatgpt_desktop_search_threads', 'chatgpt_desktop_send', 'chatgpt_desktop_status', 'chatgpt_desktop_wait_reply', 'claude_send', 'codex_send', 'codex_threads', 'codex_wait', 'codex_watch', 'gbot_bridge_start', 'gbot_bridge_status', 'gbot_bridge_stop', 'gbot_codex_respond', 'gbot_grok_approvals', 'gbot_grok_respond', 'gbot_send', 'gbot_thread']); }); it('lists and responds to an exact current Grok approval through the native API', async () => { From f4e3b67126391868171d2c040592f91a5b0037e4 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 01:24:54 +0000 Subject: [PATCH 10/26] feat: merge remote-control threads into desktop list Parse ~/.codex/.codex-global-state.json remote-thread-summaries-v3 defensively and merge into chatgpt_desktop_list_threads with location, hostId, hostName, host filter, and groupBy=host. read_thread returns a typed remote error with a host app-server hint. Fixture-backed tests. Co-authored-by: Zack Jackson --- .changeset/chatgpt-desktop-cdp.md | 2 +- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 667 +++++++++++++++-- artifact/bin/gbot.mjs | 688 ++++++++++++++--- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 705 +++++++++++++++--- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 705 +++++++++++++++--- docs/chatgpt-desktop-cdp.md | 23 +- src/cli/chatgpt-desktop/threads.tsx | 16 +- src/core/chatgpt-desktop/adapter.ts | 8 +- .../chatgpt-desktop/app-server-fallback.ts | 46 +- src/core/chatgpt-desktop/errors.ts | 30 +- src/core/chatgpt-desktop/facade.ts | 234 +++++- src/core/chatgpt-desktop/index.ts | 9 +- src/core/chatgpt-desktop/remote-threads.ts | 307 +++++++- src/core/chatgpt-desktop/routes.ts | 19 +- src/core/chatgpt-desktop/types.ts | 20 + .../tools/chatgpt_desktop_list_threads.tsx | 11 +- .../tools/chatgpt_desktop_read_thread.tsx | 2 +- .../tools/chatgpt_desktop_search_threads.tsx | 11 +- tests/fixtures/codex-global-state-remote.json | 56 ++ tests/route-unit/chatgpt-desktop.test.ts | 148 +++- 22 files changed, 3252 insertions(+), 459 deletions(-) create mode 100644 tests/fixtures/codex-global-state-remote.json diff --git a/.changeset/chatgpt-desktop-cdp.md b/.changeset/chatgpt-desktop-cdp.md index 0ea8c8f..ace22d3 100644 --- a/.changeset/chatgpt-desktop-cdp.md +++ b/.changeset/chatgpt-desktop-cdp.md @@ -2,4 +2,4 @@ "grok-bot-cli": minor --- -Scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools (`chatgpt_desktop_*`, `gbot chatgpt-desktop`). List/search/read prefer Codex app-server 0.158.0 (`modelProviders: []`, `thread/read` + `thread/turns/list`; no resume for reads). Send/wait/selected stay on CDP. Fixes `gbot codex list-threads` missing other providers. Reports `backend`. +Scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools (`chatgpt_desktop_*`). List/search merge local app-server threads with remote-control summaries from `.codex-global-state.json` (`location`/`hostId`/`host`/`groupBy`). Read returns a typed remote-thread error with host hint. Fixes `modelProviders: []` on list-threads. Reports `backend`. diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 2952302..57c17e4 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"3722353a3796ef633fe18957490e66a1199f8d6fbc67b3153d00890e17d804a6"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"0f79d51bb84d33a62274d6aa057e4b6a2f026e360bf7f4f41ca4a43084e0f22e"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"2959f151e202868e825754147def8bc1bad29fa8166708c1dceca8c7393b7de7"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"e9f097dd1f8925d7cb71f813e2ac786de0a06b3fd38786cfc857db6ee3156a48"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"cb1b5f1beee1135f846f1e1ba0caf78a4e8cba7abc29b12cdbb110cd05b44e25"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"16e93721146ab76a220e53147d518b38cfe73bbd06bd3a6da0a2f135db239177"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"112cf018afc4c8a0f93d4ac36594723d6c91a8bda824e87232a8da41df6d71ef"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"01067afcfdeb3718eda40356e390714c113d55cbccdf1575168e47c12917839e"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"847a4773d30de34c142927c6c2d8d63c580e8f5d4b688631ea5751e4bf08f70f"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"cb1b5f1beee1135f846f1e1ba0caf78a4e8cba7abc29b12cdbb110cd05b44e25"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 1658fd5..0289427 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"53d64ca80f7cb54b52a9c260bb71eaec4b275abd49fa739ad9ad7b5af2b7db2d","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"be4c37b608d956c615570d4a90edb128b682742262b8b62c41ee7c54d06c92bd","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"b76cad662fd181e66ac6864b4f59d1bf1b1dfc58cbe2ea20906770c7467dab68"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"8048333f655b419d49e061b80d8adba0bfa319820ec6b163e9b98c13d97172cb"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"f7c39813e719de53abbd4bd4dc99e3cc606253b3235ee04a9b346582bff771ce"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"42dba18d7b3223dbe5a96cd6fee98bd0f72f7977f5e6a801c6553f315ff94af7"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"63201b6028899f4f2b9f63381a8536c5fba09586ea81c8cf857bcaab687e9249"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"7bd4aa75c099c06f794a1d6a42de080df36dc7cdc47834b5d1b7e152d927610d"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"7332ee5b07f5c05356feac0887604b242d1b3a642b7f9a953fa0496124000f73"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"8a45cab48d9f02da4fa2118e0a238696ab2f4ee198faff45ac64580c1f687d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"98edba7908cecffb141018bc358074f2785baf84bd76c4e9564843d48ad9e2dd"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"6ef54c4ddb0cfccff782131120903cf8aeffde9f869887336ff7388216200201"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"fff92ea6fec1d8822f46e9d3d5e088c9c0d1f2c87773a7ec2c0e61b2b5f99535"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"029776eba4027c85f5815cf502a39fa3b7ff7c186ac992b7795f89a1b1d2a6be"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"164b99937f55ba5f4c56fd1e3bb251053c57867d93b6c641476454b527d9d5e1"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"e1498e9a15d29385dd37ca3b9395e38305d2dbdd2ae10426866f6170285c31f4"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"4c6785207b4216b2815068f68d438b3cbb6e480f684a661dc8f25d5e4b053e1b"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"9bb12f38a482e90f3a2303fb51d32e5ede3e4ccb40a42d95dded4a778b1198ca"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"655891a361725bad8463a333f9650e9ff8f70512a750c73be93a56326bd62cab"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"0ff101c427c38c9dfd699c1013c5cac4c2e5b25a3bf64602ea53c29b79363700"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"26166d29f71b43924395ef84567612093ba89d22a69c5cb4551d843a291d6689"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"0922ecf1c7a3823cd3efc7d46554b5e6e284329f0893d7ad2e1cf6263eadf67c"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"7f21f53f2ba99894d65b3dee8518f9483805fc2bda9444939a5a1fa44d74df30"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"b66856473b10327fc5c661d684b773ca0e4674821130a3072f198d498f56d8e6"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"d4282ddc4619978d0a0cf76e898d9495fc058935832a42fc8a7a14c56fa1566a"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"33f576dde77cd7cb0eb8bdad7dda58b63ec448a302b48966740ef21cdbab47e5"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22291,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"9f817266b386e10e6a8948aa180f83c7543c4b37cb1025d894883cd061362e9e"},{"bytes":1457989,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"3722353a3796ef633fe18957490e66a1199f8d6fbc67b3153d00890e17d804a6"},{"bytes":2318195,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"0f79d51bb84d33a62274d6aa057e4b6a2f026e360bf7f4f41ca4a43084e0f22e"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1375596,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"2959f151e202868e825754147def8bc1bad29fa8166708c1dceca8c7393b7de7"},{"bytes":3201729,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"e9f097dd1f8925d7cb71f813e2ac786de0a06b3fd38786cfc857db6ee3156a48"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281817,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"cb1b5f1beee1135f846f1e1ba0caf78a4e8cba7abc29b12cdbb110cd05b44e25"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.","exitCode":"result","options":[{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.","exitCode":"result","options":[{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum matches (1-200).","type":"number"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"6f7e748cd7d78a6eca00241f8c917b2bf2bb79e5e5af1d19701628b5d8bc3909","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads via app-server thread/list (modelProviders:[], useStateDbOnly). Merges CDP-only UI fields (selected, pinned overlay) when CDP is connected. Desktop local: strips to bare app-server ids. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. DOM harvest/wheel is fallback only when app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server (thread/list with modelProviders:[]), matching name/preview/cwd/project/model fields. Merges CDP selected/pinned when connected. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"limit":{"description":"Maximum matches (1-200).","type":"number"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"8d7da26a208daba2f01936da4ff41ef1b323af6f554bc966f0c1f35e3009799e","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"e0a3032b7ad4a09b3d1e6e147f2da8e8f0d9167030dbc139055985239cb4c98b","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"406b1f82b6c7225a1cbbffb201fdc628c6bdb6aee85319a2020b49d3dedd33ad"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"9f759aa54376d5c4a15379062a36f313699416573b77a1cb427698eefab2d55d"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"f7c39813e719de53abbd4bd4dc99e3cc606253b3235ee04a9b346582bff771ce"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"42dba18d7b3223dbe5a96cd6fee98bd0f72f7977f5e6a801c6553f315ff94af7"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"f67c250a2c4782fa7de84fb11d58233c775dc75beef8730118412abe71b4209d"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"4bc901aafd21db850516dbd71fe7bbe07192b2052b7d202c88fa90c53ade2ee3"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"2b702242143aced01100bc95be40ffd41e72863496ed4e041fbc24cc68506fa9"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"8a45cab48d9f02da4fa2118e0a238696ab2f4ee198faff45ac64580c1f687d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"98edba7908cecffb141018bc358074f2785baf84bd76c4e9564843d48ad9e2dd"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"a7304f85f284dd0724475fed292a4ea17714b49061a0f6a6921d0d9899b1fa05"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"a57cb0a5ab3e7fc87331c09d4672a1266c22632594e9546aad79d907bbb63d61"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"d092282751a9572fe65b135192201070da4fb75b2517267ee090846e3d6ea57e"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"c9f96c4d20d2f8c07c603ed404517d9184712730bd1283a813454b14014f8386"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"fc81f39813276989cd0e5cd62ae93febf077380bd678f71235c82d1dc60d8c63"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"4c6785207b4216b2815068f68d438b3cbb6e480f684a661dc8f25d5e4b053e1b"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"817d0a0aa9496a3b1b7235a6cbb0b83cc1fde087a3279437925d512089d6797a"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"655891a361725bad8463a333f9650e9ff8f70512a750c73be93a56326bd62cab"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"603719e36242d374225a0de767f1014dc6dae2c0819ff9405fdb806736a93d01"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"54b5d7fdb29c98d09f3bec8d4f03efdd2abf9a8b1026aed5cb4f1b890def281a"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"7f21f53f2ba99894d65b3dee8518f9483805fc2bda9444939a5a1fa44d74df30"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"b66856473b10327fc5c661d684b773ca0e4674821130a3072f198d498f56d8e6"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"d4282ddc4619978d0a0cf76e898d9495fc058935832a42fc8a7a14c56fa1566a"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"418981b646ce72e99f803ee763fa971ba7aa4b1eff6201c2c9d8271e8109bf55"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22291,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"6fef17dd2b46fc7d05c4f47cd3b0bf981a0911eab9578405c641a0687f3cd9a4"},{"bytes":1477411,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"16e93721146ab76a220e53147d518b38cfe73bbd06bd3a6da0a2f135db239177"},{"bytes":2338537,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"112cf018afc4c8a0f93d4ac36594723d6c91a8bda824e87232a8da41df6d71ef"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1396734,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"01067afcfdeb3718eda40356e390714c113d55cbccdf1575168e47c12917839e"},{"bytes":3223043,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"847a4773d30de34c142927c6c2d8d63c580e8f5d4b688631ea5751e4bf08f70f"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281817,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"cb1b5f1beee1135f846f1e1ba0caf78a4e8cba7abc29b12cdbb110cd05b44e25"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.","exitCode":"result","options":[{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads; optional --host and --group-by host.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter by hostId or friendly name (local for local-only)","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads; optional --host and --group-by host.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter by hostId or friendly name (local for local-only)","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter by hostId or friendly name (local for local-only)","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Filter by hostId or friendly host/env name (use \"local\" for local-only).","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Filter by hostId or friendly host/env name (use \"local\" for local-only).","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"cce12bbd861fd28d22a048dff73ca2bd24af2be91556b18e9167d8721ebfee23","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list (modelProviders:[]) merged with remote-control summaries from ~/.codex/.codex-global-state.json (remote-thread-summaries-v3:). Each thread has location local|remote and hostId/hostName. Optional host filter and groupBy=host. Merges CDP selected when connected. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Filter by hostId or friendly host/env name (use \"local\" for local-only).","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries in ~/.codex/.codex-global-state.json. Optional host filter and groupBy=host. Merges CDP selected/pinned when connected. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Filter by hostId or friendly host/env name (use \"local\" for local-only).","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index cb3f7ab..cb9bf64 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -8861,11 +8861,22 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.', + description: 'List local + remote-control ChatGPT Desktop threads; optional --host and --group-by host.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, properties: { + groupBy: { + description: 'Group results by host', + enum: [ + 'host' + ], + type: 'string' + }, + host: { + description: 'Filter by hostId or friendly name (local for local-only)', + type: 'string' + }, limit: { default: 50, description: 'Max threads (1-200)', @@ -8880,6 +8891,8 @@ var __webpack_modules__ = { } }; const inputSchema = zod__rspack_import_2.Ikc({ + groupBy: zod__rspack_import_2.euz('host').optional(), + host: zod__rspack_import_2.YjP().min(1).max(256).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() }).strict(); @@ -8888,7 +8901,8 @@ var __webpack_modules__ = { const threads = Array.isArray(out.threads) ? out.threads : []; const text = threads.length > 0 ? threads.map((thread)=>{ const row = thread; - return `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : ''); + const where = row.location === 'remote' ? ` [remote ${row.hostName || row.hostId || '?'}]` : ' [local]'; + return `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : '') + where; }).join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { value: out, @@ -11233,6 +11247,30 @@ var __webpack_modules__ = { } async function appServerReadThread({ threadId, limit = 100, full = false }) { const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); + const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); + if (remote) { + try { + return await readLocalThread(bare, { + limit, + full + }); + } catch (error) { + if (isThreadNotLoaded(error) || isUnknownThread(error)) { + throw new _errors_js__rspack_import_1.Rg(bare, remote.hostId, remote.hostName); + } + throw maybeRemoteThreadError(error, bare); + } + } + try { + return await readLocalThread(bare, { + limit, + full + }); + } catch (error) { + throw maybeRemoteThreadError(error, bare); + } + } + async function readLocalThread(bare, { limit, full }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { const meta = await readThreadMetadata(client, bare); @@ -11252,8 +11290,6 @@ var __webpack_modules__ = { modelProvider: meta.modelProvider, model: meta.model }; - } catch (error) { - throw maybeRemoteThreadError(error, bare); } finally{ client.close(); } @@ -11279,6 +11315,9 @@ var __webpack_modules__ = { pinned, selected: false, kind: 'codex', + location: 'local', + hostId: null, + hostName: null, preview: typeof thread.preview === 'string' ? thread.preview : undefined, cwd: thread.cwd ?? null, createdAt: thread.createdAt ?? null, @@ -11498,11 +11537,19 @@ var __webpack_modules__ = { const message = errorMessage(error); return /thread not loaded|not loaded|invalid thread id/i.test(message); } + function isUnknownThread(error) { + const message = errorMessage(error); + return /no rollout found|thread not found|unknown.*thread/i.test(message); + } function maybeRemoteThreadError(error, threadId) { const message = errorMessage(error); - if (/thread not loaded|not loaded/i.test(message)) { - const hostId = (0, _remote_threads_js__rspack_import_2.X)(threadId); - return new _errors_js__rspack_import_1.Rg(threadId, hostId); + if (/thread not loaded|not loaded|no rollout found|thread not found/i.test(message)) { + const remote = (0, _remote_threads_js__rspack_import_2.KI)(threadId); + if (remote) { + return new _errors_js__rspack_import_1.Rg(threadId, remote.hostId, remote.hostName); + } + const hostId = (0, _remote_threads_js__rspack_import_2.XI)(threadId); + return new _errors_js__rspack_import_1.Rg(threadId, hostId, null); } if (error instanceof Error) return error; return new Error(message || `app-server error for thread ${threadId}`); @@ -12402,12 +12449,18 @@ var __webpack_modules__ = { reason = 'remote-thread-not-loaded'; threadId; hostId; - constructor(threadId, hostId = null){ - const owner = hostId ? `owned by remote-control host ${JSON.stringify(hostId)}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; - super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ` + `${owner}. SSH remoting is not implemented in this adapter yet.`); + hostName; + hint; + constructor(threadId, hostId = null, hostName = null){ + const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; + const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); this.name = 'RemoteThreadNotLoadedError'; this.threadId = threadId; this.hostId = hostId; + this.hostName = hostName; + this.hint = hint; } } __webpack_require__.d(__webpack_exports__, { @@ -12422,12 +12475,14 @@ var __webpack_modules__ = { var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); - var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _remote_threads_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _thread_ids_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, - statusProbe: _app_server_fallback_js__rspack_import_1.dM + statusProbe: _app_server_fallback_js__rspack_import_1.dM, + listRemoteThreads: _remote_threads_js__rspack_import_4.Hx }; class ChatGptDesktopFacade { #cdp; @@ -12455,11 +12510,14 @@ var __webpack_modules__ = { await this.#ensureCdp(); return this.#cdp.listTargets(); } - async listThreads(options) { + async listThreads(options = {}) { + const limit = options.limit ?? 50; let appList = null; let appError; try { - appList = await this.#fallbacks.listThreads(options); + appList = await this.#fallbacks.listThreads({ + limit + }); } catch (error) { appError = error; } @@ -12467,7 +12525,9 @@ var __webpack_modules__ = { let cdpError; try { await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads(options); + cdpList = await this.#cdp.listThreads({ + limit + }); } catch (error) { if (isCdpFailure(error)) { this.#cdpConnected = false; @@ -12475,47 +12535,71 @@ var __webpack_modules__ = { cdpError = error; } } - if (appList && cdpList) { - return mergeThreadLists(appList, cdpList); - } - if (appList) return appList; - if (cdpList) return cdpList; - if (cdpError) throw cdpError; - if (appError) throw appError; - throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); + let base = null; + if (appList && cdpList) base = mergeThreadLists(appList, cdpList); + else if (appList) base = appList; + else if (cdpList) base = cdpList; + else if (cdpError) throw cdpError; + else if (appError) throw appError; + else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); + return finalizeThreadList(base, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: this.#listRemotes() + }); } async searchThreads(options) { + const limit = options.limit ?? 50; try { - const appList = await this.#fallbacks.searchThreads(options); + const appList = await this.#fallbacks.searchThreads({ + query: options.query, + limit + }); const cdpList = await this.#tryCdpList({ - limit: options.limit + limit + }); + const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const withRemotes = finalizeThreadList(base, { + limit: 10000, + host: options.host, + remotes: this.#listRemotes() + }); + const needle = options.query.trim().toLowerCase(); + const filtered = { + ...withRemotes, + query: options.query, + threads: withRemotes.threads.filter((thread)=>threadMatchesQuery(thread, needle)) + }; + return finalizeThreadList(filtered, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: [] }); - if (cdpList) return mergeThreadLists(appList, cdpList); - return appList; } catch (appError) { const cdpList = await this.#tryCdpList({ - limit: options.limit + limit }); if (!cdpList) throw appError; const needle = options.query.trim().toLowerCase(); - return { + const filtered = { ...cdpList, query: options.query, - threads: cdpList.threads.filter((thread)=>{ - if (!needle) return true; - return [ - thread.title, - thread.threadId, - thread.project - ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); - }) + threads: cdpList.threads.filter((thread)=>threadMatchesQuery(thread, needle)) }; + return finalizeThreadList(filtered, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: this.#listRemotes() + }); } } async readThread(options) { const limit = options.limit ?? 100; const full = options.full ?? false; - if ((0, _thread_ids_js__rspack_import_4.vr)(options.threadId)) { + if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { await this.#ensureCdp(); return this.#cdp.readThread({ ...options, @@ -12530,6 +12614,7 @@ var __webpack_modules__ = { full }); } catch (appError) { + if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; return this.#cdp.readThread({ @@ -12575,6 +12660,14 @@ var __webpack_modules__ = { this.#cdpConnected = false; await this.#cdp.close(); } + #listRemotes() { + const list = this.#fallbacks.listRemoteThreads ?? _remote_threads_js__rspack_import_4.Hx; + try { + return list(); + } catch { + return []; + } + } async #ensureCdp() { if (this.#cdpConnected) return; await this.#cdp.connect({ @@ -12608,35 +12701,139 @@ var __webpack_modules__ = { function mergeThreadLists(appList, cdpList) { const cdpByKey = new Map(); for (const thread of cdpList.threads){ - const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; cdpByKey.set(key, thread); } const merged = appList.threads.map((thread)=>{ - const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; const cdp = cdpByKey.get(key); - if (!cdp) return thread; - return { + const withLocal = { ...thread, - title: thread.title || cdp.title, - pinned: thread.pinned || cdp.pinned, + location: thread.location ?? 'local', + hostId: thread.hostId ?? null, + hostName: thread.hostName ?? null + }; + if (!cdp) return withLocal; + return { + ...withLocal, + title: withLocal.title || cdp.title, + pinned: withLocal.pinned || cdp.pinned, selected: cdp.selected, - kind: cdp.kind || thread.kind, - project: cdp.project ?? thread.project + kind: cdp.kind || withLocal.kind, + project: cdp.project ?? withLocal.project }; }); for (const thread of cdpList.threads){ - if (merged.some((row)=>(0, _thread_ids_js__rspack_import_4.LV)(row.threadId, thread.threadId))) continue; - merged.push(thread); + if (merged.some((row)=>(0, _thread_ids_js__rspack_import_5.LV)(row.threadId, thread.threadId))) continue; + merged.push({ + ...thread, + location: thread.location ?? 'local', + hostId: thread.hostId ?? null, + hostName: thread.hostName ?? null + }); } return { - backend: 'app-server', + backend: appList.backend, limit: appList.limit, nextCursor: appList.nextCursor, ...appList.query !== undefined ? { query: appList.query } : {}, - threads: merged.slice(0, appList.limit) + threads: merged + }; + } + function finalizeThreadList(base, { limit, host, groupBy, remotes }) { + const locals = base.threads.map((thread)=>{ + const location = thread.location ?? 'local'; + return { + ...thread, + location, + hostId: location === 'remote' ? thread.hostId ?? null : null, + hostName: location === 'remote' ? thread.hostName ?? null : null + }; + }); + const localKeys = new Set(locals.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + const merged = [ + ...locals + ]; + for (const remote of remotes){ + const key = (0, _thread_ids_js__rspack_import_5.nn)(remote.threadId) ?? remote.threadId; + if (localKeys.has(key)) continue; + merged.push({ + ...remote, + location: remote.location ?? 'remote', + hostId: remote.hostId ?? null, + hostName: remote.hostName ?? null + }); + } + const filtered = host ? merged.filter((thread)=>hostMatches(thread, host)) : merged; + const limited = filtered.slice(0, limit); + const result = { + backend: base.backend, + limit, + threads: limited, + ...base.nextCursor !== undefined ? { + nextCursor: base.nextCursor + } : {}, + ...base.query !== undefined ? { + query: base.query + } : {}, + ...host ? { + host + } : {} }; + if (groupBy === 'host') { + return { + ...result, + groupBy: 'host', + groups: groupThreadsByHost(limited) + }; + } + return result; + } + function groupThreadsByHost(threads) { + const groups = new Map(); + for (const thread of threads){ + const location = thread.location ?? 'local'; + const hostId = location === 'remote' ? thread.hostId || 'unknown-remote' : 'local'; + const key = `${location}:${hostId}`; + const existing = groups.get(key); + if (existing) { + existing.threads.push(thread); + continue; + } + groups.set(key, { + hostId, + hostName: thread.hostName ?? (location === 'local' ? 'local' : null), + location, + threads: [ + thread + ] + }); + } + return [ + ...groups.values() + ]; + } + function hostMatches(thread, host) { + const needle = host.trim().toLowerCase(); + if (!needle) return true; + if (needle === 'local') return (thread.location ?? 'local') === 'local'; + return [ + thread.hostId, + thread.hostName + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } + function threadMatchesQuery(thread, needle) { + if (!needle) return true; + return [ + thread.title, + thread.threadId, + thread.project, + thread.preview, + thread.hostName, + thread.hostId + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); } function isCdpFailure(error) { if (error instanceof _errors_js__rspack_import_2.sO) return true; @@ -12730,62 +12927,356 @@ var __webpack_modules__ = { const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); } - function findRemoteThreadHostId(threadId, env = process.env) { - const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; - if (!bare) return null; + function loadCodexGlobalState(env = process.env) { let raw; try { raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); } catch { return null; } - let data; try { - data = JSON.parse(raw); + const data = JSON.parse(raw); + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + return data; } catch { return null; } - if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + } + function listRemoteThreadsFromState(env = process.env) { + const data = loadCodexGlobalState(env); + if (!data) return []; + const hostNames = collectHostNames(data); + const out = []; + const seen = new Set(); for (const [key, value] of Object.entries(data)){ const match = REMOTE_SUMMARY_KEY.exec(key); - if (!match) continue; - if (summariesIncludeThread(value, bare)) return match[1] ?? null; + if (!match?.[1]) continue; + const hostId = match[1]; + const hostName = hostNames.get(hostId) ?? extractHostName(value); + const pinnedIds = extractPinnedIds(value); + for (const entry of extractThreadEntries(value)){ + const mapped = mapRemoteEntry(entry, { + hostId, + hostName, + pinnedIds + }); + if (!mapped) continue; + const bare = (0, _thread_ids_js__rspack_import_3.nn)(mapped.threadId) ?? mapped.threadId; + const dedupe = `${hostId}:${bare}`; + if (seen.has(dedupe)) continue; + seen.add(dedupe); + out.push(mapped); + } } - return null; + return out; } - function summariesIncludeThread(value, threadId) { - if (Array.isArray(value)) { - return value.some((entry)=>entryMentionsThread(entry, threadId)); + function findRemoteThread(threadId, env = process.env) { + const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; + if (!bare) return null; + for (const thread of listRemoteThreadsFromState(env)){ + const id = (0, _thread_ids_js__rspack_import_3.nn)(thread.threadId) ?? thread.threadId; + if (id === bare) { + return { + hostId: thread.hostId, + hostName: thread.hostName, + thread + }; + } } - if (value && typeof value === 'object') { - const record = value; - if (threadId in record) return true; - if (Array.isArray(record.threads)) { - return record.threads.some((entry)=>entryMentionsThread(entry, threadId)); + return null; + } + function findRemoteThreadHostId(threadId, env = process.env) { + return findRemoteThread(threadId, env)?.hostId ?? null; + } + function collectHostNames(data) { + const names = new Map(); + for (const [key, value] of Object.entries(data)){ + if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; + if (!value || typeof value !== 'object') continue; + if (Array.isArray(value)) { + for (const entry of value){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + continue; } - if (Array.isArray(record.summaries)) { - return record.summaries.some((entry)=>entryMentionsThread(entry, threadId)); + for (const [hostId, entry] of Object.entries(value)){ + const fromEntry = hostNameFromEntry(entry); + if (fromEntry) { + names.set(fromEntry.hostId, fromEntry.hostName); + continue; + } + const label = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (label) names.set(hostId, label); } - return Object.values(record).some((entry)=>entryMentionsThread(entry, threadId)); } - return false; + return names; } - function entryMentionsThread(entry, threadId) { - if (typeof entry === 'string') return entry === threadId; - if (!entry || typeof entry !== 'object') return false; + function hostNameFromEntry(entry) { + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; const row = entry; + const hostId = stringField(row, [ + 'hostId', + 'id', + 'host_id', + 'uuid' + ]); + const hostName = stringField(row, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (!hostId || !hostName) return null; + return { + hostId, + hostName + }; + } + function extractHostName(value) { + if (!value || typeof value !== 'object' || Array.isArray(value)) return null; + return stringField(value, [ + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName' + ]); + } + function extractPinnedIds(value) { + const pinned = new Set(); + if (!value || typeof value !== 'object') return pinned; + const record = value; + for (const key of [ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'pinned_ids' + ]){ + const arr = record[key]; + if (!Array.isArray(arr)) continue; + for (const item of arr){ + if (typeof item === 'string' && item) pinned.add(item); + else if (item && typeof item === 'object') { + const id = stringField(item, [ + 'id', + 'threadId', + 'thread_id' + ]); + if (id) pinned.add(id); + } + } + } + return pinned; + } + function extractThreadEntries(value) { + if (Array.isArray(value)) return value; + if (!value || typeof value !== 'object') return []; + const record = value; for (const key of [ + 'threads', + 'summaries', + 'items', + 'data', + 'conversations' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + const entries = []; + for (const [key, entry] of Object.entries(record)){ + if ([ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName', + 'hostId', + 'version' + ].includes(key)) { + continue; + } + if (typeof entry === 'string') continue; + if (entry && typeof entry === 'object' && !Array.isArray(entry)) { + const row = entry; + if (!stringField(row, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ])) { + entries.push({ + ...row, + id: key + }); + } else { + entries.push(entry); + } + } + } + return entries; + } + function mapRemoteEntry(entry, { hostId, hostName, pinnedIds }) { + if (typeof entry === 'string' && entry) { + return { + threadId: (0, _thread_ids_js__rspack_import_3.BS)(entry), + title: entry, + pinned: pinnedIds.has(entry), + selected: false, + kind: 'remote', + location: 'remote', + hostId, + hostName + }; + } + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + const row = entry; + const id = stringField(row, [ 'id', 'threadId', 'thread_id', 'conversationId' - ]){ - if (row[key] === threadId) return true; + ]); + if (!id) return null; + const title = stringField(row, [ + 'title', + 'name', + 'preview', + 'label' + ]) || id; + const projectId = stringField(row, [ + 'projectId', + 'project_id' + ]); + const project = stringField(row, [ + 'project', + 'projectName', + 'project_name', + 'cwd' + ]) || projectId || undefined; + const preview = stringField(row, [ + 'preview', + 'snippet' + ]); + const cwd = stringField(row, [ + 'cwd', + 'workingDirectory', + 'working_directory' + ]); + const modelProvider = stringField(row, [ + 'modelProvider', + 'model_provider', + 'provider' + ]); + const model = stringField(row, [ + 'model' + ]); + const originator = stringField(row, [ + 'originator', + 'source' + ]); + const createdAt = numberField(row, [ + 'createdAt', + 'created_at' + ]); + const updatedAt = numberField(row, [ + 'updatedAt', + 'updated_at' + ]); + const sectionName = stringField(row, [ + 'sectionName', + 'section' + ]); + const sectionId = stringField(row, [ + 'sectionId', + 'section_id' + ]) || sectionName; + const pinned = pinnedIds.has(id) || row.pinned === true || sectionId === 'Pinned' || sectionName === 'Pinned'; + return { + threadId: (0, _thread_ids_js__rspack_import_3.BS)(id), + title, + pinned, + selected: false, + kind: 'remote', + location: 'remote', + hostId, + hostName, + ...project ? { + project + } : {}, + ...projectId ? { + projectId + } : {}, + ...preview ? { + preview + } : {}, + ...cwd ? { + cwd + } : { + cwd: null + }, + createdAt: createdAt ?? null, + updatedAt: updatedAt ?? null, + ...sectionId ? { + section: { + id: sectionId, + name: sectionName ?? sectionId + } + } : { + section: null + }, + ...modelProvider ? { + modelProvider + } : { + modelProvider: null + }, + ...model ? { + model + } : { + model: null + }, + ...originator ? { + originator + } : { + originator: null + } + }; + } + function stringField(row, keys) { + if (!row || typeof row !== 'object' || Array.isArray(row)) return null; + const record = row; + for (const key of keys){ + const value = record[key]; + if (typeof value === 'string' && value.trim()) return value.trim(); } - return false; + return null; + } + function numberField(row, keys) { + for (const key of keys){ + const value = row[key]; + if (typeof value === 'number' && Number.isFinite(value)) return value; + } + return null; } __webpack_require__.d(__webpack_exports__, { - X: ()=>findRemoteThreadHostId + Hx: ()=>listRemoteThreadsFromState, + KI: ()=>findRemoteThread, + XI: ()=>findRemoteThreadHostId }); }, "./src/core/chatgpt-desktop/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -12800,12 +13291,16 @@ var __webpack_modules__ = { }).strict(); const listThreadsSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), - limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const searchThreadsSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), query: zod__rspack_import_4.YjP().min(1).max(512), - limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), @@ -12863,9 +13358,13 @@ var __webpack_modules__ = { code: error.code, error: error.message, threadId: error.threadId, + hint: error.hint, ...error.hostId ? { hostId: error.hostId } : {}, + ...error.hostName ? { + hostName: error.hostName + } : {}, exitCode: 1 }); } @@ -12889,7 +13388,9 @@ var __webpack_modules__ = { async function listThreadsOperation(input) { try { const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ - limit: input.limit + limit: input.limit, + host: input.host, + groupBy: input.groupBy })); return asResult({ ...out, @@ -12907,7 +13408,9 @@ var __webpack_modules__ = { } return adapter.searchThreads({ query: input.query, - limit: input.limit + limit: input.limit, + host: input.host, + groupBy: input.groupBy }); }); return asResult({ diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index 5433b03..28941a4 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -7269,11 +7269,22 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.', + description: 'List local + remote-control ChatGPT Desktop threads; optional --host and --group-by host.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, properties: { + groupBy: { + description: 'Group results by host', + enum: [ + 'host' + ], + type: 'string' + }, + host: { + description: 'Filter by hostId or friendly name (local for local-only)', + type: 'string' + }, limit: { default: 50, description: 'Max threads (1-200)', @@ -7288,6 +7299,8 @@ var __webpack_modules__ = { } }; const inputSchema = zod__rspack_import_2.Ikc({ + groupBy: zod__rspack_import_2.euz('host').optional(), + host: zod__rspack_import_2.YjP().min(1).max(256).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() }).strict(); @@ -7296,7 +7309,8 @@ var __webpack_modules__ = { const threads = Array.isArray(out.threads) ? out.threads : []; const text = threads.length > 0 ? threads.map((thread)=>{ const row = thread; - return `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : ''); + const where = row.location === 'remote' ? ` [remote ${row.hostName || row.hostId || '?'}]` : ' [local]'; + return `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : '') + where; }).join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { value: out, @@ -9641,6 +9655,30 @@ var __webpack_modules__ = { } async function appServerReadThread({ threadId, limit = 100, full = false }) { const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); + const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); + if (remote) { + try { + return await readLocalThread(bare, { + limit, + full + }); + } catch (error) { + if (isThreadNotLoaded(error) || isUnknownThread(error)) { + throw new _errors_js__rspack_import_1.Rg(bare, remote.hostId, remote.hostName); + } + throw maybeRemoteThreadError(error, bare); + } + } + try { + return await readLocalThread(bare, { + limit, + full + }); + } catch (error) { + throw maybeRemoteThreadError(error, bare); + } + } + async function readLocalThread(bare, { limit, full }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { const meta = await readThreadMetadata(client, bare); @@ -9660,8 +9698,6 @@ var __webpack_modules__ = { modelProvider: meta.modelProvider, model: meta.model }; - } catch (error) { - throw maybeRemoteThreadError(error, bare); } finally{ client.close(); } @@ -9687,6 +9723,9 @@ var __webpack_modules__ = { pinned, selected: false, kind: 'codex', + location: 'local', + hostId: null, + hostName: null, preview: typeof thread.preview === 'string' ? thread.preview : undefined, cwd: thread.cwd ?? null, createdAt: thread.createdAt ?? null, @@ -9906,11 +9945,19 @@ var __webpack_modules__ = { const message = errorMessage(error); return /thread not loaded|not loaded|invalid thread id/i.test(message); } + function isUnknownThread(error) { + const message = errorMessage(error); + return /no rollout found|thread not found|unknown.*thread/i.test(message); + } function maybeRemoteThreadError(error, threadId) { const message = errorMessage(error); - if (/thread not loaded|not loaded/i.test(message)) { - const hostId = (0, _remote_threads_js__rspack_import_2.X)(threadId); - return new _errors_js__rspack_import_1.Rg(threadId, hostId); + if (/thread not loaded|not loaded|no rollout found|thread not found/i.test(message)) { + const remote = (0, _remote_threads_js__rspack_import_2.KI)(threadId); + if (remote) { + return new _errors_js__rspack_import_1.Rg(threadId, remote.hostId, remote.hostName); + } + const hostId = (0, _remote_threads_js__rspack_import_2.XI)(threadId); + return new _errors_js__rspack_import_1.Rg(threadId, hostId, null); } if (error instanceof Error) return error; return new Error(message || `app-server error for thread ${threadId}`); @@ -10810,12 +10857,18 @@ var __webpack_modules__ = { reason = 'remote-thread-not-loaded'; threadId; hostId; - constructor(threadId, hostId = null){ - const owner = hostId ? `owned by remote-control host ${JSON.stringify(hostId)}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; - super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ` + `${owner}. SSH remoting is not implemented in this adapter yet.`); + hostName; + hint; + constructor(threadId, hostId = null, hostName = null){ + const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; + const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); this.name = 'RemoteThreadNotLoadedError'; this.threadId = threadId; this.hostId = hostId; + this.hostName = hostName; + this.hint = hint; } } __webpack_require__.d(__webpack_exports__, { @@ -10830,12 +10883,14 @@ var __webpack_modules__ = { var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); - var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _remote_threads_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _thread_ids_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, - statusProbe: _app_server_fallback_js__rspack_import_1.dM + statusProbe: _app_server_fallback_js__rspack_import_1.dM, + listRemoteThreads: _remote_threads_js__rspack_import_4.Hx }; class ChatGptDesktopFacade { #cdp; @@ -10863,11 +10918,14 @@ var __webpack_modules__ = { await this.#ensureCdp(); return this.#cdp.listTargets(); } - async listThreads(options) { + async listThreads(options = {}) { + const limit = options.limit ?? 50; let appList = null; let appError; try { - appList = await this.#fallbacks.listThreads(options); + appList = await this.#fallbacks.listThreads({ + limit + }); } catch (error) { appError = error; } @@ -10875,7 +10933,9 @@ var __webpack_modules__ = { let cdpError; try { await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads(options); + cdpList = await this.#cdp.listThreads({ + limit + }); } catch (error) { if (isCdpFailure(error)) { this.#cdpConnected = false; @@ -10883,47 +10943,71 @@ var __webpack_modules__ = { cdpError = error; } } - if (appList && cdpList) { - return mergeThreadLists(appList, cdpList); - } - if (appList) return appList; - if (cdpList) return cdpList; - if (cdpError) throw cdpError; - if (appError) throw appError; - throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); + let base = null; + if (appList && cdpList) base = mergeThreadLists(appList, cdpList); + else if (appList) base = appList; + else if (cdpList) base = cdpList; + else if (cdpError) throw cdpError; + else if (appError) throw appError; + else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); + return finalizeThreadList(base, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: this.#listRemotes() + }); } async searchThreads(options) { + const limit = options.limit ?? 50; try { - const appList = await this.#fallbacks.searchThreads(options); + const appList = await this.#fallbacks.searchThreads({ + query: options.query, + limit + }); const cdpList = await this.#tryCdpList({ - limit: options.limit + limit + }); + const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const withRemotes = finalizeThreadList(base, { + limit: 10000, + host: options.host, + remotes: this.#listRemotes() + }); + const needle = options.query.trim().toLowerCase(); + const filtered = { + ...withRemotes, + query: options.query, + threads: withRemotes.threads.filter((thread)=>threadMatchesQuery(thread, needle)) + }; + return finalizeThreadList(filtered, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: [] }); - if (cdpList) return mergeThreadLists(appList, cdpList); - return appList; } catch (appError) { const cdpList = await this.#tryCdpList({ - limit: options.limit + limit }); if (!cdpList) throw appError; const needle = options.query.trim().toLowerCase(); - return { + const filtered = { ...cdpList, query: options.query, - threads: cdpList.threads.filter((thread)=>{ - if (!needle) return true; - return [ - thread.title, - thread.threadId, - thread.project - ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); - }) + threads: cdpList.threads.filter((thread)=>threadMatchesQuery(thread, needle)) }; + return finalizeThreadList(filtered, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: this.#listRemotes() + }); } } async readThread(options) { const limit = options.limit ?? 100; const full = options.full ?? false; - if ((0, _thread_ids_js__rspack_import_4.vr)(options.threadId)) { + if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { await this.#ensureCdp(); return this.#cdp.readThread({ ...options, @@ -10938,6 +11022,7 @@ var __webpack_modules__ = { full }); } catch (appError) { + if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; return this.#cdp.readThread({ @@ -10983,6 +11068,14 @@ var __webpack_modules__ = { this.#cdpConnected = false; await this.#cdp.close(); } + #listRemotes() { + const list = this.#fallbacks.listRemoteThreads ?? _remote_threads_js__rspack_import_4.Hx; + try { + return list(); + } catch { + return []; + } + } async #ensureCdp() { if (this.#cdpConnected) return; await this.#cdp.connect({ @@ -11016,35 +11109,139 @@ var __webpack_modules__ = { function mergeThreadLists(appList, cdpList) { const cdpByKey = new Map(); for (const thread of cdpList.threads){ - const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; cdpByKey.set(key, thread); } const merged = appList.threads.map((thread)=>{ - const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; const cdp = cdpByKey.get(key); - if (!cdp) return thread; - return { + const withLocal = { ...thread, - title: thread.title || cdp.title, - pinned: thread.pinned || cdp.pinned, + location: thread.location ?? 'local', + hostId: thread.hostId ?? null, + hostName: thread.hostName ?? null + }; + if (!cdp) return withLocal; + return { + ...withLocal, + title: withLocal.title || cdp.title, + pinned: withLocal.pinned || cdp.pinned, selected: cdp.selected, - kind: cdp.kind || thread.kind, - project: cdp.project ?? thread.project + kind: cdp.kind || withLocal.kind, + project: cdp.project ?? withLocal.project }; }); for (const thread of cdpList.threads){ - if (merged.some((row)=>(0, _thread_ids_js__rspack_import_4.LV)(row.threadId, thread.threadId))) continue; - merged.push(thread); + if (merged.some((row)=>(0, _thread_ids_js__rspack_import_5.LV)(row.threadId, thread.threadId))) continue; + merged.push({ + ...thread, + location: thread.location ?? 'local', + hostId: thread.hostId ?? null, + hostName: thread.hostName ?? null + }); } return { - backend: 'app-server', + backend: appList.backend, limit: appList.limit, nextCursor: appList.nextCursor, ...appList.query !== undefined ? { query: appList.query } : {}, - threads: merged.slice(0, appList.limit) + threads: merged + }; + } + function finalizeThreadList(base, { limit, host, groupBy, remotes }) { + const locals = base.threads.map((thread)=>{ + const location = thread.location ?? 'local'; + return { + ...thread, + location, + hostId: location === 'remote' ? thread.hostId ?? null : null, + hostName: location === 'remote' ? thread.hostName ?? null : null + }; + }); + const localKeys = new Set(locals.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + const merged = [ + ...locals + ]; + for (const remote of remotes){ + const key = (0, _thread_ids_js__rspack_import_5.nn)(remote.threadId) ?? remote.threadId; + if (localKeys.has(key)) continue; + merged.push({ + ...remote, + location: remote.location ?? 'remote', + hostId: remote.hostId ?? null, + hostName: remote.hostName ?? null + }); + } + const filtered = host ? merged.filter((thread)=>hostMatches(thread, host)) : merged; + const limited = filtered.slice(0, limit); + const result = { + backend: base.backend, + limit, + threads: limited, + ...base.nextCursor !== undefined ? { + nextCursor: base.nextCursor + } : {}, + ...base.query !== undefined ? { + query: base.query + } : {}, + ...host ? { + host + } : {} }; + if (groupBy === 'host') { + return { + ...result, + groupBy: 'host', + groups: groupThreadsByHost(limited) + }; + } + return result; + } + function groupThreadsByHost(threads) { + const groups = new Map(); + for (const thread of threads){ + const location = thread.location ?? 'local'; + const hostId = location === 'remote' ? thread.hostId || 'unknown-remote' : 'local'; + const key = `${location}:${hostId}`; + const existing = groups.get(key); + if (existing) { + existing.threads.push(thread); + continue; + } + groups.set(key, { + hostId, + hostName: thread.hostName ?? (location === 'local' ? 'local' : null), + location, + threads: [ + thread + ] + }); + } + return [ + ...groups.values() + ]; + } + function hostMatches(thread, host) { + const needle = host.trim().toLowerCase(); + if (!needle) return true; + if (needle === 'local') return (thread.location ?? 'local') === 'local'; + return [ + thread.hostId, + thread.hostName + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } + function threadMatchesQuery(thread, needle) { + if (!needle) return true; + return [ + thread.title, + thread.threadId, + thread.project, + thread.preview, + thread.hostName, + thread.hostId + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); } function isCdpFailure(error) { if (error instanceof _errors_js__rspack_import_2.sO) return true; @@ -11138,62 +11335,356 @@ var __webpack_modules__ = { const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); } - function findRemoteThreadHostId(threadId, env = process.env) { - const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; - if (!bare) return null; + function loadCodexGlobalState(env = process.env) { let raw; try { raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); } catch { return null; } - let data; try { - data = JSON.parse(raw); + const data = JSON.parse(raw); + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + return data; } catch { return null; } - if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + } + function listRemoteThreadsFromState(env = process.env) { + const data = loadCodexGlobalState(env); + if (!data) return []; + const hostNames = collectHostNames(data); + const out = []; + const seen = new Set(); for (const [key, value] of Object.entries(data)){ const match = REMOTE_SUMMARY_KEY.exec(key); - if (!match) continue; - if (summariesIncludeThread(value, bare)) return match[1] ?? null; + if (!match?.[1]) continue; + const hostId = match[1]; + const hostName = hostNames.get(hostId) ?? extractHostName(value); + const pinnedIds = extractPinnedIds(value); + for (const entry of extractThreadEntries(value)){ + const mapped = mapRemoteEntry(entry, { + hostId, + hostName, + pinnedIds + }); + if (!mapped) continue; + const bare = (0, _thread_ids_js__rspack_import_3.nn)(mapped.threadId) ?? mapped.threadId; + const dedupe = `${hostId}:${bare}`; + if (seen.has(dedupe)) continue; + seen.add(dedupe); + out.push(mapped); + } } - return null; + return out; } - function summariesIncludeThread(value, threadId) { - if (Array.isArray(value)) { - return value.some((entry)=>entryMentionsThread(entry, threadId)); + function findRemoteThread(threadId, env = process.env) { + const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; + if (!bare) return null; + for (const thread of listRemoteThreadsFromState(env)){ + const id = (0, _thread_ids_js__rspack_import_3.nn)(thread.threadId) ?? thread.threadId; + if (id === bare) { + return { + hostId: thread.hostId, + hostName: thread.hostName, + thread + }; + } } - if (value && typeof value === 'object') { - const record = value; - if (threadId in record) return true; - if (Array.isArray(record.threads)) { - return record.threads.some((entry)=>entryMentionsThread(entry, threadId)); + return null; + } + function findRemoteThreadHostId(threadId, env = process.env) { + return findRemoteThread(threadId, env)?.hostId ?? null; + } + function collectHostNames(data) { + const names = new Map(); + for (const [key, value] of Object.entries(data)){ + if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; + if (!value || typeof value !== 'object') continue; + if (Array.isArray(value)) { + for (const entry of value){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + continue; } - if (Array.isArray(record.summaries)) { - return record.summaries.some((entry)=>entryMentionsThread(entry, threadId)); + for (const [hostId, entry] of Object.entries(value)){ + const fromEntry = hostNameFromEntry(entry); + if (fromEntry) { + names.set(fromEntry.hostId, fromEntry.hostName); + continue; + } + const label = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (label) names.set(hostId, label); } - return Object.values(record).some((entry)=>entryMentionsThread(entry, threadId)); } - return false; + return names; } - function entryMentionsThread(entry, threadId) { - if (typeof entry === 'string') return entry === threadId; - if (!entry || typeof entry !== 'object') return false; + function hostNameFromEntry(entry) { + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; const row = entry; + const hostId = stringField(row, [ + 'hostId', + 'id', + 'host_id', + 'uuid' + ]); + const hostName = stringField(row, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (!hostId || !hostName) return null; + return { + hostId, + hostName + }; + } + function extractHostName(value) { + if (!value || typeof value !== 'object' || Array.isArray(value)) return null; + return stringField(value, [ + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName' + ]); + } + function extractPinnedIds(value) { + const pinned = new Set(); + if (!value || typeof value !== 'object') return pinned; + const record = value; for (const key of [ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'pinned_ids' + ]){ + const arr = record[key]; + if (!Array.isArray(arr)) continue; + for (const item of arr){ + if (typeof item === 'string' && item) pinned.add(item); + else if (item && typeof item === 'object') { + const id = stringField(item, [ + 'id', + 'threadId', + 'thread_id' + ]); + if (id) pinned.add(id); + } + } + } + return pinned; + } + function extractThreadEntries(value) { + if (Array.isArray(value)) return value; + if (!value || typeof value !== 'object') return []; + const record = value; + for (const key of [ + 'threads', + 'summaries', + 'items', + 'data', + 'conversations' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + const entries = []; + for (const [key, entry] of Object.entries(record)){ + if ([ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName', + 'hostId', + 'version' + ].includes(key)) { + continue; + } + if (typeof entry === 'string') continue; + if (entry && typeof entry === 'object' && !Array.isArray(entry)) { + const row = entry; + if (!stringField(row, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ])) { + entries.push({ + ...row, + id: key + }); + } else { + entries.push(entry); + } + } + } + return entries; + } + function mapRemoteEntry(entry, { hostId, hostName, pinnedIds }) { + if (typeof entry === 'string' && entry) { + return { + threadId: (0, _thread_ids_js__rspack_import_3.BS)(entry), + title: entry, + pinned: pinnedIds.has(entry), + selected: false, + kind: 'remote', + location: 'remote', + hostId, + hostName + }; + } + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + const row = entry; + const id = stringField(row, [ 'id', 'threadId', 'thread_id', 'conversationId' - ]){ - if (row[key] === threadId) return true; + ]); + if (!id) return null; + const title = stringField(row, [ + 'title', + 'name', + 'preview', + 'label' + ]) || id; + const projectId = stringField(row, [ + 'projectId', + 'project_id' + ]); + const project = stringField(row, [ + 'project', + 'projectName', + 'project_name', + 'cwd' + ]) || projectId || undefined; + const preview = stringField(row, [ + 'preview', + 'snippet' + ]); + const cwd = stringField(row, [ + 'cwd', + 'workingDirectory', + 'working_directory' + ]); + const modelProvider = stringField(row, [ + 'modelProvider', + 'model_provider', + 'provider' + ]); + const model = stringField(row, [ + 'model' + ]); + const originator = stringField(row, [ + 'originator', + 'source' + ]); + const createdAt = numberField(row, [ + 'createdAt', + 'created_at' + ]); + const updatedAt = numberField(row, [ + 'updatedAt', + 'updated_at' + ]); + const sectionName = stringField(row, [ + 'sectionName', + 'section' + ]); + const sectionId = stringField(row, [ + 'sectionId', + 'section_id' + ]) || sectionName; + const pinned = pinnedIds.has(id) || row.pinned === true || sectionId === 'Pinned' || sectionName === 'Pinned'; + return { + threadId: (0, _thread_ids_js__rspack_import_3.BS)(id), + title, + pinned, + selected: false, + kind: 'remote', + location: 'remote', + hostId, + hostName, + ...project ? { + project + } : {}, + ...projectId ? { + projectId + } : {}, + ...preview ? { + preview + } : {}, + ...cwd ? { + cwd + } : { + cwd: null + }, + createdAt: createdAt ?? null, + updatedAt: updatedAt ?? null, + ...sectionId ? { + section: { + id: sectionId, + name: sectionName ?? sectionId + } + } : { + section: null + }, + ...modelProvider ? { + modelProvider + } : { + modelProvider: null + }, + ...model ? { + model + } : { + model: null + }, + ...originator ? { + originator + } : { + originator: null + } + }; + } + function stringField(row, keys) { + if (!row || typeof row !== 'object' || Array.isArray(row)) return null; + const record = row; + for (const key of keys){ + const value = record[key]; + if (typeof value === 'string' && value.trim()) return value.trim(); } - return false; + return null; + } + function numberField(row, keys) { + for (const key of keys){ + const value = row[key]; + if (typeof value === 'number' && Number.isFinite(value)) return value; + } + return null; } __webpack_require__.d(__webpack_exports__, { - X: ()=>findRemoteThreadHostId + Hx: ()=>listRemoteThreadsFromState, + KI: ()=>findRemoteThread, + XI: ()=>findRemoteThreadHostId }); }, "./src/core/chatgpt-desktop/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -11208,12 +11699,16 @@ var __webpack_modules__ = { }).strict(); const listThreadsSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), - limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const searchThreadsSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), query: zod__rspack_import_4.YjP().min(1).max(512), - limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), @@ -11271,9 +11766,13 @@ var __webpack_modules__ = { code: error.code, error: error.message, threadId: error.threadId, + hint: error.hint, ...error.hostId ? { hostId: error.hostId } : {}, + ...error.hostName ? { + hostName: error.hostName + } : {}, exitCode: 1 }); } @@ -11297,7 +11796,9 @@ var __webpack_modules__ = { async function listThreadsOperation(input) { try { const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ - limit: input.limit + limit: input.limit, + host: input.host, + groupBy: input.groupBy })); return asResult({ ...out, @@ -11315,7 +11816,9 @@ var __webpack_modules__ = { } return adapter.searchThreads({ query: input.query, - limit: input.limit + limit: input.limit, + host: input.host, + groupBy: input.groupBy }); }); return asResult({ @@ -39851,9 +40354,28 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.", + "description": "List local + remote-control ChatGPT Desktop threads; optional --host and --group-by host.", "exitCode": "result", "options": [ + { + "choices": [ + "host" + ], + "description": "Group results by host", + "key": "groupBy", + "kind": "enum", + "option": "group-by", + "repeated": false, + "required": false + }, + { + "description": "Filter by hostId or friendly name (local for local-only)", + "key": "host", + "kind": "string", + "option": "host", + "repeated": false, + "required": false + }, { "defaultValue": 50, "description": "Max threads (1-200)", diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index 0c5d51b..7af5ca2 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8133,6 +8133,30 @@ var __webpack_modules__ = { } async function appServerReadThread({ threadId, limit = 100, full = false }) { const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); + const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); + if (remote) { + try { + return await readLocalThread(bare, { + limit, + full + }); + } catch (error) { + if (isThreadNotLoaded(error) || isUnknownThread(error)) { + throw new _errors_js__rspack_import_1.Rg(bare, remote.hostId, remote.hostName); + } + throw maybeRemoteThreadError(error, bare); + } + } + try { + return await readLocalThread(bare, { + limit, + full + }); + } catch (error) { + throw maybeRemoteThreadError(error, bare); + } + } + async function readLocalThread(bare, { limit, full }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { const meta = await readThreadMetadata(client, bare); @@ -8152,8 +8176,6 @@ var __webpack_modules__ = { modelProvider: meta.modelProvider, model: meta.model }; - } catch (error) { - throw maybeRemoteThreadError(error, bare); } finally{ client.close(); } @@ -8179,6 +8201,9 @@ var __webpack_modules__ = { pinned, selected: false, kind: 'codex', + location: 'local', + hostId: null, + hostName: null, preview: typeof thread.preview === 'string' ? thread.preview : undefined, cwd: thread.cwd ?? null, createdAt: thread.createdAt ?? null, @@ -8398,11 +8423,19 @@ var __webpack_modules__ = { const message = errorMessage(error); return /thread not loaded|not loaded|invalid thread id/i.test(message); } + function isUnknownThread(error) { + const message = errorMessage(error); + return /no rollout found|thread not found|unknown.*thread/i.test(message); + } function maybeRemoteThreadError(error, threadId) { const message = errorMessage(error); - if (/thread not loaded|not loaded/i.test(message)) { - const hostId = (0, _remote_threads_js__rspack_import_2.X)(threadId); - return new _errors_js__rspack_import_1.Rg(threadId, hostId); + if (/thread not loaded|not loaded|no rollout found|thread not found/i.test(message)) { + const remote = (0, _remote_threads_js__rspack_import_2.KI)(threadId); + if (remote) { + return new _errors_js__rspack_import_1.Rg(threadId, remote.hostId, remote.hostName); + } + const hostId = (0, _remote_threads_js__rspack_import_2.XI)(threadId); + return new _errors_js__rspack_import_1.Rg(threadId, hostId, null); } if (error instanceof Error) return error; return new Error(message || `app-server error for thread ${threadId}`); @@ -9302,12 +9335,18 @@ var __webpack_modules__ = { reason = 'remote-thread-not-loaded'; threadId; hostId; - constructor(threadId, hostId = null){ - const owner = hostId ? `owned by remote-control host ${JSON.stringify(hostId)}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; - super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ` + `${owner}. SSH remoting is not implemented in this adapter yet.`); + hostName; + hint; + constructor(threadId, hostId = null, hostName = null){ + const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; + const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); this.name = 'RemoteThreadNotLoadedError'; this.threadId = threadId; this.hostId = hostId; + this.hostName = hostName; + this.hint = hint; } } __webpack_require__.d(__webpack_exports__, { @@ -9322,12 +9361,14 @@ var __webpack_modules__ = { var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); - var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _remote_threads_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _thread_ids_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, - statusProbe: _app_server_fallback_js__rspack_import_1.dM + statusProbe: _app_server_fallback_js__rspack_import_1.dM, + listRemoteThreads: _remote_threads_js__rspack_import_4.Hx }; class ChatGptDesktopFacade { #cdp; @@ -9355,11 +9396,14 @@ var __webpack_modules__ = { await this.#ensureCdp(); return this.#cdp.listTargets(); } - async listThreads(options) { + async listThreads(options = {}) { + const limit = options.limit ?? 50; let appList = null; let appError; try { - appList = await this.#fallbacks.listThreads(options); + appList = await this.#fallbacks.listThreads({ + limit + }); } catch (error) { appError = error; } @@ -9367,7 +9411,9 @@ var __webpack_modules__ = { let cdpError; try { await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads(options); + cdpList = await this.#cdp.listThreads({ + limit + }); } catch (error) { if (isCdpFailure(error)) { this.#cdpConnected = false; @@ -9375,47 +9421,71 @@ var __webpack_modules__ = { cdpError = error; } } - if (appList && cdpList) { - return mergeThreadLists(appList, cdpList); - } - if (appList) return appList; - if (cdpList) return cdpList; - if (cdpError) throw cdpError; - if (appError) throw appError; - throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); + let base = null; + if (appList && cdpList) base = mergeThreadLists(appList, cdpList); + else if (appList) base = appList; + else if (cdpList) base = cdpList; + else if (cdpError) throw cdpError; + else if (appError) throw appError; + else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); + return finalizeThreadList(base, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: this.#listRemotes() + }); } async searchThreads(options) { + const limit = options.limit ?? 50; try { - const appList = await this.#fallbacks.searchThreads(options); + const appList = await this.#fallbacks.searchThreads({ + query: options.query, + limit + }); const cdpList = await this.#tryCdpList({ - limit: options.limit + limit + }); + const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const withRemotes = finalizeThreadList(base, { + limit: 10000, + host: options.host, + remotes: this.#listRemotes() + }); + const needle = options.query.trim().toLowerCase(); + const filtered = { + ...withRemotes, + query: options.query, + threads: withRemotes.threads.filter((thread)=>threadMatchesQuery(thread, needle)) + }; + return finalizeThreadList(filtered, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: [] }); - if (cdpList) return mergeThreadLists(appList, cdpList); - return appList; } catch (appError) { const cdpList = await this.#tryCdpList({ - limit: options.limit + limit }); if (!cdpList) throw appError; const needle = options.query.trim().toLowerCase(); - return { + const filtered = { ...cdpList, query: options.query, - threads: cdpList.threads.filter((thread)=>{ - if (!needle) return true; - return [ - thread.title, - thread.threadId, - thread.project - ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); - }) + threads: cdpList.threads.filter((thread)=>threadMatchesQuery(thread, needle)) }; + return finalizeThreadList(filtered, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: this.#listRemotes() + }); } } async readThread(options) { const limit = options.limit ?? 100; const full = options.full ?? false; - if ((0, _thread_ids_js__rspack_import_4.vr)(options.threadId)) { + if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { await this.#ensureCdp(); return this.#cdp.readThread({ ...options, @@ -9430,6 +9500,7 @@ var __webpack_modules__ = { full }); } catch (appError) { + if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; return this.#cdp.readThread({ @@ -9475,6 +9546,14 @@ var __webpack_modules__ = { this.#cdpConnected = false; await this.#cdp.close(); } + #listRemotes() { + const list = this.#fallbacks.listRemoteThreads ?? _remote_threads_js__rspack_import_4.Hx; + try { + return list(); + } catch { + return []; + } + } async #ensureCdp() { if (this.#cdpConnected) return; await this.#cdp.connect({ @@ -9508,36 +9587,140 @@ var __webpack_modules__ = { function mergeThreadLists(appList, cdpList) { const cdpByKey = new Map(); for (const thread of cdpList.threads){ - const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; cdpByKey.set(key, thread); } const merged = appList.threads.map((thread)=>{ - const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; const cdp = cdpByKey.get(key); - if (!cdp) return thread; - return { + const withLocal = { ...thread, - title: thread.title || cdp.title, - pinned: thread.pinned || cdp.pinned, + location: thread.location ?? 'local', + hostId: thread.hostId ?? null, + hostName: thread.hostName ?? null + }; + if (!cdp) return withLocal; + return { + ...withLocal, + title: withLocal.title || cdp.title, + pinned: withLocal.pinned || cdp.pinned, selected: cdp.selected, - kind: cdp.kind || thread.kind, - project: cdp.project ?? thread.project + kind: cdp.kind || withLocal.kind, + project: cdp.project ?? withLocal.project }; }); for (const thread of cdpList.threads){ - if (merged.some((row)=>(0, _thread_ids_js__rspack_import_4.LV)(row.threadId, thread.threadId))) continue; - merged.push(thread); + if (merged.some((row)=>(0, _thread_ids_js__rspack_import_5.LV)(row.threadId, thread.threadId))) continue; + merged.push({ + ...thread, + location: thread.location ?? 'local', + hostId: thread.hostId ?? null, + hostName: thread.hostName ?? null + }); } return { - backend: 'app-server', + backend: appList.backend, limit: appList.limit, nextCursor: appList.nextCursor, ...appList.query !== undefined ? { query: appList.query } : {}, - threads: merged.slice(0, appList.limit) + threads: merged }; } + function finalizeThreadList(base, { limit, host, groupBy, remotes }) { + const locals = base.threads.map((thread)=>{ + const location = thread.location ?? 'local'; + return { + ...thread, + location, + hostId: location === 'remote' ? thread.hostId ?? null : null, + hostName: location === 'remote' ? thread.hostName ?? null : null + }; + }); + const localKeys = new Set(locals.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + const merged = [ + ...locals + ]; + for (const remote of remotes){ + const key = (0, _thread_ids_js__rspack_import_5.nn)(remote.threadId) ?? remote.threadId; + if (localKeys.has(key)) continue; + merged.push({ + ...remote, + location: remote.location ?? 'remote', + hostId: remote.hostId ?? null, + hostName: remote.hostName ?? null + }); + } + const filtered = host ? merged.filter((thread)=>hostMatches(thread, host)) : merged; + const limited = filtered.slice(0, limit); + const result = { + backend: base.backend, + limit, + threads: limited, + ...base.nextCursor !== undefined ? { + nextCursor: base.nextCursor + } : {}, + ...base.query !== undefined ? { + query: base.query + } : {}, + ...host ? { + host + } : {} + }; + if (groupBy === 'host') { + return { + ...result, + groupBy: 'host', + groups: groupThreadsByHost(limited) + }; + } + return result; + } + function groupThreadsByHost(threads) { + const groups = new Map(); + for (const thread of threads){ + const location = thread.location ?? 'local'; + const hostId = location === 'remote' ? thread.hostId || 'unknown-remote' : 'local'; + const key = `${location}:${hostId}`; + const existing = groups.get(key); + if (existing) { + existing.threads.push(thread); + continue; + } + groups.set(key, { + hostId, + hostName: thread.hostName ?? (location === 'local' ? 'local' : null), + location, + threads: [ + thread + ] + }); + } + return [ + ...groups.values() + ]; + } + function hostMatches(thread, host) { + const needle = host.trim().toLowerCase(); + if (!needle) return true; + if (needle === 'local') return (thread.location ?? 'local') === 'local'; + return [ + thread.hostId, + thread.hostName + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } + function threadMatchesQuery(thread, needle) { + if (!needle) return true; + return [ + thread.title, + thread.threadId, + thread.project, + thread.preview, + thread.hostName, + thread.hostId + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } function isCdpFailure(error) { if (error instanceof _errors_js__rspack_import_2.sO) return true; if (error instanceof _errors_js__rspack_import_2.EH) return false; @@ -9630,62 +9813,356 @@ var __webpack_modules__ = { const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); } - function findRemoteThreadHostId(threadId, env = process.env) { - const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; - if (!bare) return null; + function loadCodexGlobalState(env = process.env) { let raw; try { raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); } catch { return null; } - let data; try { - data = JSON.parse(raw); + const data = JSON.parse(raw); + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + return data; } catch { return null; } - if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + } + function listRemoteThreadsFromState(env = process.env) { + const data = loadCodexGlobalState(env); + if (!data) return []; + const hostNames = collectHostNames(data); + const out = []; + const seen = new Set(); for (const [key, value] of Object.entries(data)){ const match = REMOTE_SUMMARY_KEY.exec(key); - if (!match) continue; - if (summariesIncludeThread(value, bare)) return match[1] ?? null; + if (!match?.[1]) continue; + const hostId = match[1]; + const hostName = hostNames.get(hostId) ?? extractHostName(value); + const pinnedIds = extractPinnedIds(value); + for (const entry of extractThreadEntries(value)){ + const mapped = mapRemoteEntry(entry, { + hostId, + hostName, + pinnedIds + }); + if (!mapped) continue; + const bare = (0, _thread_ids_js__rspack_import_3.nn)(mapped.threadId) ?? mapped.threadId; + const dedupe = `${hostId}:${bare}`; + if (seen.has(dedupe)) continue; + seen.add(dedupe); + out.push(mapped); + } } - return null; + return out; } - function summariesIncludeThread(value, threadId) { - if (Array.isArray(value)) { - return value.some((entry)=>entryMentionsThread(entry, threadId)); + function findRemoteThread(threadId, env = process.env) { + const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; + if (!bare) return null; + for (const thread of listRemoteThreadsFromState(env)){ + const id = (0, _thread_ids_js__rspack_import_3.nn)(thread.threadId) ?? thread.threadId; + if (id === bare) { + return { + hostId: thread.hostId, + hostName: thread.hostName, + thread + }; + } } - if (value && typeof value === 'object') { - const record = value; - if (threadId in record) return true; - if (Array.isArray(record.threads)) { - return record.threads.some((entry)=>entryMentionsThread(entry, threadId)); + return null; + } + function findRemoteThreadHostId(threadId, env = process.env) { + return findRemoteThread(threadId, env)?.hostId ?? null; + } + function collectHostNames(data) { + const names = new Map(); + for (const [key, value] of Object.entries(data)){ + if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; + if (!value || typeof value !== 'object') continue; + if (Array.isArray(value)) { + for (const entry of value){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + continue; } - if (Array.isArray(record.summaries)) { - return record.summaries.some((entry)=>entryMentionsThread(entry, threadId)); + for (const [hostId, entry] of Object.entries(value)){ + const fromEntry = hostNameFromEntry(entry); + if (fromEntry) { + names.set(fromEntry.hostId, fromEntry.hostName); + continue; + } + const label = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (label) names.set(hostId, label); } - return Object.values(record).some((entry)=>entryMentionsThread(entry, threadId)); } - return false; + return names; } - function entryMentionsThread(entry, threadId) { - if (typeof entry === 'string') return entry === threadId; - if (!entry || typeof entry !== 'object') return false; + function hostNameFromEntry(entry) { + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; const row = entry; + const hostId = stringField(row, [ + 'hostId', + 'id', + 'host_id', + 'uuid' + ]); + const hostName = stringField(row, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (!hostId || !hostName) return null; + return { + hostId, + hostName + }; + } + function extractHostName(value) { + if (!value || typeof value !== 'object' || Array.isArray(value)) return null; + return stringField(value, [ + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName' + ]); + } + function extractPinnedIds(value) { + const pinned = new Set(); + if (!value || typeof value !== 'object') return pinned; + const record = value; for (const key of [ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'pinned_ids' + ]){ + const arr = record[key]; + if (!Array.isArray(arr)) continue; + for (const item of arr){ + if (typeof item === 'string' && item) pinned.add(item); + else if (item && typeof item === 'object') { + const id = stringField(item, [ + 'id', + 'threadId', + 'thread_id' + ]); + if (id) pinned.add(id); + } + } + } + return pinned; + } + function extractThreadEntries(value) { + if (Array.isArray(value)) return value; + if (!value || typeof value !== 'object') return []; + const record = value; + for (const key of [ + 'threads', + 'summaries', + 'items', + 'data', + 'conversations' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + const entries = []; + for (const [key, entry] of Object.entries(record)){ + if ([ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName', + 'hostId', + 'version' + ].includes(key)) { + continue; + } + if (typeof entry === 'string') continue; + if (entry && typeof entry === 'object' && !Array.isArray(entry)) { + const row = entry; + if (!stringField(row, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ])) { + entries.push({ + ...row, + id: key + }); + } else { + entries.push(entry); + } + } + } + return entries; + } + function mapRemoteEntry(entry, { hostId, hostName, pinnedIds }) { + if (typeof entry === 'string' && entry) { + return { + threadId: (0, _thread_ids_js__rspack_import_3.BS)(entry), + title: entry, + pinned: pinnedIds.has(entry), + selected: false, + kind: 'remote', + location: 'remote', + hostId, + hostName + }; + } + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + const row = entry; + const id = stringField(row, [ 'id', 'threadId', 'thread_id', 'conversationId' - ]){ - if (row[key] === threadId) return true; + ]); + if (!id) return null; + const title = stringField(row, [ + 'title', + 'name', + 'preview', + 'label' + ]) || id; + const projectId = stringField(row, [ + 'projectId', + 'project_id' + ]); + const project = stringField(row, [ + 'project', + 'projectName', + 'project_name', + 'cwd' + ]) || projectId || undefined; + const preview = stringField(row, [ + 'preview', + 'snippet' + ]); + const cwd = stringField(row, [ + 'cwd', + 'workingDirectory', + 'working_directory' + ]); + const modelProvider = stringField(row, [ + 'modelProvider', + 'model_provider', + 'provider' + ]); + const model = stringField(row, [ + 'model' + ]); + const originator = stringField(row, [ + 'originator', + 'source' + ]); + const createdAt = numberField(row, [ + 'createdAt', + 'created_at' + ]); + const updatedAt = numberField(row, [ + 'updatedAt', + 'updated_at' + ]); + const sectionName = stringField(row, [ + 'sectionName', + 'section' + ]); + const sectionId = stringField(row, [ + 'sectionId', + 'section_id' + ]) || sectionName; + const pinned = pinnedIds.has(id) || row.pinned === true || sectionId === 'Pinned' || sectionName === 'Pinned'; + return { + threadId: (0, _thread_ids_js__rspack_import_3.BS)(id), + title, + pinned, + selected: false, + kind: 'remote', + location: 'remote', + hostId, + hostName, + ...project ? { + project + } : {}, + ...projectId ? { + projectId + } : {}, + ...preview ? { + preview + } : {}, + ...cwd ? { + cwd + } : { + cwd: null + }, + createdAt: createdAt ?? null, + updatedAt: updatedAt ?? null, + ...sectionId ? { + section: { + id: sectionId, + name: sectionName ?? sectionId + } + } : { + section: null + }, + ...modelProvider ? { + modelProvider + } : { + modelProvider: null + }, + ...model ? { + model + } : { + model: null + }, + ...originator ? { + originator + } : { + originator: null + } + }; + } + function stringField(row, keys) { + if (!row || typeof row !== 'object' || Array.isArray(row)) return null; + const record = row; + for (const key of keys){ + const value = record[key]; + if (typeof value === 'string' && value.trim()) return value.trim(); } - return false; + return null; + } + function numberField(row, keys) { + for (const key of keys){ + const value = row[key]; + if (typeof value === 'number' && Number.isFinite(value)) return value; + } + return null; } __webpack_require__.d(__webpack_exports__, { - X: ()=>findRemoteThreadHostId + Hx: ()=>listRemoteThreadsFromState, + KI: ()=>findRemoteThread, + XI: ()=>findRemoteThreadHostId }); }, "./src/core/chatgpt-desktop/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -9700,12 +10177,16 @@ var __webpack_modules__ = { }).strict(); const listThreadsSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), - limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const searchThreadsSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), query: zod__rspack_import_4.YjP().min(1).max(512), - limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), @@ -9763,9 +10244,13 @@ var __webpack_modules__ = { code: error.code, error: error.message, threadId: error.threadId, + hint: error.hint, ...error.hostId ? { hostId: error.hostId } : {}, + ...error.hostName ? { + hostName: error.hostName + } : {}, exitCode: 1 }); } @@ -9789,7 +10274,9 @@ var __webpack_modules__ = { async function listThreadsOperation(input) { try { const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ - limit: input.limit + limit: input.limit, + host: input.host, + groupBy: input.groupBy })); return asResult({ ...out, @@ -9807,7 +10294,9 @@ var __webpack_modules__ = { } return adapter.searchThreads({ query: input.query, - limit: input.limit + limit: input.limit, + host: input.host, + groupBy: input.groupBy }); }); return asResult({ @@ -10529,7 +11018,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List ChatGPT Desktop / Codex threads via app-server thread/list (modelProviders:[], useStateDbOnly). Merges CDP-only UI fields (selected, pinned overlay) when CDP is connected. Desktop local: strips to bare app-server ids. Result includes backend.', + description: 'List ChatGPT Desktop / Codex threads: local app-server thread/list (modelProviders:[]) merged with remote-control summaries from ~/.codex/.codex-global-state.json (remote-thread-summaries-v3:). Each thread has location local|remote and hostId/hostName. Optional host filter and groupBy=host. Merges CDP selected when connected. Result includes backend.', annotations: { readOnlyHint: true }, @@ -10545,6 +11034,17 @@ var __webpack_modules__ = { limit: { type: 'number', description: 'Maximum threads (1-200).' + }, + host: { + type: 'string', + description: 'Filter by hostId or friendly host/env name (use "local" for local-only).' + }, + groupBy: { + type: 'string', + enum: [ + 'host' + ], + description: 'When "host", also return groups[] keyed by host.' } }, required: [] @@ -10572,7 +11072,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. DOM harvest/wheel is fallback only when app-server is unavailable. Result includes backend.', + description: 'Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host\'s app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.', annotations: { readOnlyHint: true }, @@ -10631,7 +11131,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop search threads', - description: 'Search ChatGPT Desktop / Codex threads through the local app-server (thread/list with modelProviders:[]), matching name/preview/cwd/project/model fields. Merges CDP selected/pinned when connected. Result includes backend.', + description: 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries in ~/.codex/.codex-global-state.json. Optional host filter and groupBy=host. Merges CDP selected/pinned when connected. Result includes backend.', annotations: { readOnlyHint: true }, @@ -10651,6 +11151,17 @@ var __webpack_modules__ = { limit: { type: 'number', description: 'Maximum matches (1-200).' + }, + host: { + type: 'string', + description: 'Filter by hostId or friendly host/env name (use "local" for local-only).' + }, + groupBy: { + type: 'string', + enum: [ + 'host' + ], + description: 'When "host", also return groups[] keyed by host.' } }, required: [ @@ -26508,10 +27019,21 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "List ChatGPT Desktop / Codex threads via app-server thread/list (modelProviders:[], useStateDbOnly). Merges CDP-only UI fields (selected, pinned overlay) when CDP is connected. Desktop local: strips to bare app-server ids. Result includes backend.", + "description": "List ChatGPT Desktop / Codex threads: local app-server thread/list (modelProviders:[]) merged with remote-control summaries from ~/.codex/.codex-global-state.json (remote-thread-summaries-v3:). Each thread has location local|remote and hostId/hostName. Optional host filter and groupBy=host. Merges CDP selected when connected. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "groupBy": { + "description": "When \"host\", also return groups[] keyed by host.", + "enum": [ + "host" + ], + "type": "string" + }, + "host": { + "description": "Filter by hostId or friendly host/env name (use \"local\" for local-only).", + "type": "string" + }, "limit": { "description": "Maximum threads (1-200).", "type": "number" @@ -26536,7 +27058,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. DOM harvest/wheel is fallback only when app-server is unavailable. Result includes backend.", + "description": "Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -26580,10 +27102,21 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Search ChatGPT Desktop / Codex threads through the local app-server (thread/list with modelProviders:[]), matching name/preview/cwd/project/model fields. Merges CDP selected/pinned when connected. Result includes backend.", + "description": "Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries in ~/.codex/.codex-global-state.json. Optional host filter and groupBy=host. Merges CDP selected/pinned when connected. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "groupBy": { + "description": "When \"host\", also return groups[] keyed by host.", + "enum": [ + "host" + ], + "type": "string" + }, + "host": { + "description": "Filter by hostId or friendly host/env name (use \"local\" for local-only).", + "type": "string" + }, "limit": { "description": "Maximum matches (1-200).", "type": "number" diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index afc8072..683081b 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -6541,6 +6541,30 @@ var __webpack_modules__ = { } async function appServerReadThread({ threadId, limit = 100, full = false }) { const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); + const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); + if (remote) { + try { + return await readLocalThread(bare, { + limit, + full + }); + } catch (error) { + if (isThreadNotLoaded(error) || isUnknownThread(error)) { + throw new _errors_js__rspack_import_1.Rg(bare, remote.hostId, remote.hostName); + } + throw maybeRemoteThreadError(error, bare); + } + } + try { + return await readLocalThread(bare, { + limit, + full + }); + } catch (error) { + throw maybeRemoteThreadError(error, bare); + } + } + async function readLocalThread(bare, { limit, full }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { const meta = await readThreadMetadata(client, bare); @@ -6560,8 +6584,6 @@ var __webpack_modules__ = { modelProvider: meta.modelProvider, model: meta.model }; - } catch (error) { - throw maybeRemoteThreadError(error, bare); } finally{ client.close(); } @@ -6587,6 +6609,9 @@ var __webpack_modules__ = { pinned, selected: false, kind: 'codex', + location: 'local', + hostId: null, + hostName: null, preview: typeof thread.preview === 'string' ? thread.preview : undefined, cwd: thread.cwd ?? null, createdAt: thread.createdAt ?? null, @@ -6806,11 +6831,19 @@ var __webpack_modules__ = { const message = errorMessage(error); return /thread not loaded|not loaded|invalid thread id/i.test(message); } + function isUnknownThread(error) { + const message = errorMessage(error); + return /no rollout found|thread not found|unknown.*thread/i.test(message); + } function maybeRemoteThreadError(error, threadId) { const message = errorMessage(error); - if (/thread not loaded|not loaded/i.test(message)) { - const hostId = (0, _remote_threads_js__rspack_import_2.X)(threadId); - return new _errors_js__rspack_import_1.Rg(threadId, hostId); + if (/thread not loaded|not loaded|no rollout found|thread not found/i.test(message)) { + const remote = (0, _remote_threads_js__rspack_import_2.KI)(threadId); + if (remote) { + return new _errors_js__rspack_import_1.Rg(threadId, remote.hostId, remote.hostName); + } + const hostId = (0, _remote_threads_js__rspack_import_2.XI)(threadId); + return new _errors_js__rspack_import_1.Rg(threadId, hostId, null); } if (error instanceof Error) return error; return new Error(message || `app-server error for thread ${threadId}`); @@ -7710,12 +7743,18 @@ var __webpack_modules__ = { reason = 'remote-thread-not-loaded'; threadId; hostId; - constructor(threadId, hostId = null){ - const owner = hostId ? `owned by remote-control host ${JSON.stringify(hostId)}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; - super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ` + `${owner}. SSH remoting is not implemented in this adapter yet.`); + hostName; + hint; + constructor(threadId, hostId = null, hostName = null){ + const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; + const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); this.name = 'RemoteThreadNotLoadedError'; this.threadId = threadId; this.hostId = hostId; + this.hostName = hostName; + this.hint = hint; } } __webpack_require__.d(__webpack_exports__, { @@ -7730,12 +7769,14 @@ var __webpack_modules__ = { var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); - var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _remote_threads_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _thread_ids_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, - statusProbe: _app_server_fallback_js__rspack_import_1.dM + statusProbe: _app_server_fallback_js__rspack_import_1.dM, + listRemoteThreads: _remote_threads_js__rspack_import_4.Hx }; class ChatGptDesktopFacade { #cdp; @@ -7763,11 +7804,14 @@ var __webpack_modules__ = { await this.#ensureCdp(); return this.#cdp.listTargets(); } - async listThreads(options) { + async listThreads(options = {}) { + const limit = options.limit ?? 50; let appList = null; let appError; try { - appList = await this.#fallbacks.listThreads(options); + appList = await this.#fallbacks.listThreads({ + limit + }); } catch (error) { appError = error; } @@ -7775,7 +7819,9 @@ var __webpack_modules__ = { let cdpError; try { await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads(options); + cdpList = await this.#cdp.listThreads({ + limit + }); } catch (error) { if (isCdpFailure(error)) { this.#cdpConnected = false; @@ -7783,47 +7829,71 @@ var __webpack_modules__ = { cdpError = error; } } - if (appList && cdpList) { - return mergeThreadLists(appList, cdpList); - } - if (appList) return appList; - if (cdpList) return cdpList; - if (cdpError) throw cdpError; - if (appError) throw appError; - throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); + let base = null; + if (appList && cdpList) base = mergeThreadLists(appList, cdpList); + else if (appList) base = appList; + else if (cdpList) base = cdpList; + else if (cdpError) throw cdpError; + else if (appError) throw appError; + else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); + return finalizeThreadList(base, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: this.#listRemotes() + }); } async searchThreads(options) { + const limit = options.limit ?? 50; try { - const appList = await this.#fallbacks.searchThreads(options); + const appList = await this.#fallbacks.searchThreads({ + query: options.query, + limit + }); const cdpList = await this.#tryCdpList({ - limit: options.limit + limit + }); + const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const withRemotes = finalizeThreadList(base, { + limit: 10000, + host: options.host, + remotes: this.#listRemotes() + }); + const needle = options.query.trim().toLowerCase(); + const filtered = { + ...withRemotes, + query: options.query, + threads: withRemotes.threads.filter((thread)=>threadMatchesQuery(thread, needle)) + }; + return finalizeThreadList(filtered, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: [] }); - if (cdpList) return mergeThreadLists(appList, cdpList); - return appList; } catch (appError) { const cdpList = await this.#tryCdpList({ - limit: options.limit + limit }); if (!cdpList) throw appError; const needle = options.query.trim().toLowerCase(); - return { + const filtered = { ...cdpList, query: options.query, - threads: cdpList.threads.filter((thread)=>{ - if (!needle) return true; - return [ - thread.title, - thread.threadId, - thread.project - ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); - }) + threads: cdpList.threads.filter((thread)=>threadMatchesQuery(thread, needle)) }; + return finalizeThreadList(filtered, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: this.#listRemotes() + }); } } async readThread(options) { const limit = options.limit ?? 100; const full = options.full ?? false; - if ((0, _thread_ids_js__rspack_import_4.vr)(options.threadId)) { + if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { await this.#ensureCdp(); return this.#cdp.readThread({ ...options, @@ -7838,6 +7908,7 @@ var __webpack_modules__ = { full }); } catch (appError) { + if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; return this.#cdp.readThread({ @@ -7883,6 +7954,14 @@ var __webpack_modules__ = { this.#cdpConnected = false; await this.#cdp.close(); } + #listRemotes() { + const list = this.#fallbacks.listRemoteThreads ?? _remote_threads_js__rspack_import_4.Hx; + try { + return list(); + } catch { + return []; + } + } async #ensureCdp() { if (this.#cdpConnected) return; await this.#cdp.connect({ @@ -7916,35 +7995,139 @@ var __webpack_modules__ = { function mergeThreadLists(appList, cdpList) { const cdpByKey = new Map(); for (const thread of cdpList.threads){ - const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; cdpByKey.set(key, thread); } const merged = appList.threads.map((thread)=>{ - const key = (0, _thread_ids_js__rspack_import_4.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; const cdp = cdpByKey.get(key); - if (!cdp) return thread; - return { + const withLocal = { ...thread, - title: thread.title || cdp.title, - pinned: thread.pinned || cdp.pinned, + location: thread.location ?? 'local', + hostId: thread.hostId ?? null, + hostName: thread.hostName ?? null + }; + if (!cdp) return withLocal; + return { + ...withLocal, + title: withLocal.title || cdp.title, + pinned: withLocal.pinned || cdp.pinned, selected: cdp.selected, - kind: cdp.kind || thread.kind, - project: cdp.project ?? thread.project + kind: cdp.kind || withLocal.kind, + project: cdp.project ?? withLocal.project }; }); for (const thread of cdpList.threads){ - if (merged.some((row)=>(0, _thread_ids_js__rspack_import_4.LV)(row.threadId, thread.threadId))) continue; - merged.push(thread); + if (merged.some((row)=>(0, _thread_ids_js__rspack_import_5.LV)(row.threadId, thread.threadId))) continue; + merged.push({ + ...thread, + location: thread.location ?? 'local', + hostId: thread.hostId ?? null, + hostName: thread.hostName ?? null + }); } return { - backend: 'app-server', + backend: appList.backend, limit: appList.limit, nextCursor: appList.nextCursor, ...appList.query !== undefined ? { query: appList.query } : {}, - threads: merged.slice(0, appList.limit) + threads: merged + }; + } + function finalizeThreadList(base, { limit, host, groupBy, remotes }) { + const locals = base.threads.map((thread)=>{ + const location = thread.location ?? 'local'; + return { + ...thread, + location, + hostId: location === 'remote' ? thread.hostId ?? null : null, + hostName: location === 'remote' ? thread.hostName ?? null : null + }; + }); + const localKeys = new Set(locals.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + const merged = [ + ...locals + ]; + for (const remote of remotes){ + const key = (0, _thread_ids_js__rspack_import_5.nn)(remote.threadId) ?? remote.threadId; + if (localKeys.has(key)) continue; + merged.push({ + ...remote, + location: remote.location ?? 'remote', + hostId: remote.hostId ?? null, + hostName: remote.hostName ?? null + }); + } + const filtered = host ? merged.filter((thread)=>hostMatches(thread, host)) : merged; + const limited = filtered.slice(0, limit); + const result = { + backend: base.backend, + limit, + threads: limited, + ...base.nextCursor !== undefined ? { + nextCursor: base.nextCursor + } : {}, + ...base.query !== undefined ? { + query: base.query + } : {}, + ...host ? { + host + } : {} }; + if (groupBy === 'host') { + return { + ...result, + groupBy: 'host', + groups: groupThreadsByHost(limited) + }; + } + return result; + } + function groupThreadsByHost(threads) { + const groups = new Map(); + for (const thread of threads){ + const location = thread.location ?? 'local'; + const hostId = location === 'remote' ? thread.hostId || 'unknown-remote' : 'local'; + const key = `${location}:${hostId}`; + const existing = groups.get(key); + if (existing) { + existing.threads.push(thread); + continue; + } + groups.set(key, { + hostId, + hostName: thread.hostName ?? (location === 'local' ? 'local' : null), + location, + threads: [ + thread + ] + }); + } + return [ + ...groups.values() + ]; + } + function hostMatches(thread, host) { + const needle = host.trim().toLowerCase(); + if (!needle) return true; + if (needle === 'local') return (thread.location ?? 'local') === 'local'; + return [ + thread.hostId, + thread.hostName + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } + function threadMatchesQuery(thread, needle) { + if (!needle) return true; + return [ + thread.title, + thread.threadId, + thread.project, + thread.preview, + thread.hostName, + thread.hostId + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); } function isCdpFailure(error) { if (error instanceof _errors_js__rspack_import_2.sO) return true; @@ -8038,62 +8221,356 @@ var __webpack_modules__ = { const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); } - function findRemoteThreadHostId(threadId, env = process.env) { - const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; - if (!bare) return null; + function loadCodexGlobalState(env = process.env) { let raw; try { raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); } catch { return null; } - let data; try { - data = JSON.parse(raw); + const data = JSON.parse(raw); + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + return data; } catch { return null; } - if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + } + function listRemoteThreadsFromState(env = process.env) { + const data = loadCodexGlobalState(env); + if (!data) return []; + const hostNames = collectHostNames(data); + const out = []; + const seen = new Set(); for (const [key, value] of Object.entries(data)){ const match = REMOTE_SUMMARY_KEY.exec(key); - if (!match) continue; - if (summariesIncludeThread(value, bare)) return match[1] ?? null; + if (!match?.[1]) continue; + const hostId = match[1]; + const hostName = hostNames.get(hostId) ?? extractHostName(value); + const pinnedIds = extractPinnedIds(value); + for (const entry of extractThreadEntries(value)){ + const mapped = mapRemoteEntry(entry, { + hostId, + hostName, + pinnedIds + }); + if (!mapped) continue; + const bare = (0, _thread_ids_js__rspack_import_3.nn)(mapped.threadId) ?? mapped.threadId; + const dedupe = `${hostId}:${bare}`; + if (seen.has(dedupe)) continue; + seen.add(dedupe); + out.push(mapped); + } } - return null; + return out; } - function summariesIncludeThread(value, threadId) { - if (Array.isArray(value)) { - return value.some((entry)=>entryMentionsThread(entry, threadId)); + function findRemoteThread(threadId, env = process.env) { + const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; + if (!bare) return null; + for (const thread of listRemoteThreadsFromState(env)){ + const id = (0, _thread_ids_js__rspack_import_3.nn)(thread.threadId) ?? thread.threadId; + if (id === bare) { + return { + hostId: thread.hostId, + hostName: thread.hostName, + thread + }; + } } - if (value && typeof value === 'object') { - const record = value; - if (threadId in record) return true; - if (Array.isArray(record.threads)) { - return record.threads.some((entry)=>entryMentionsThread(entry, threadId)); + return null; + } + function findRemoteThreadHostId(threadId, env = process.env) { + return findRemoteThread(threadId, env)?.hostId ?? null; + } + function collectHostNames(data) { + const names = new Map(); + for (const [key, value] of Object.entries(data)){ + if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; + if (!value || typeof value !== 'object') continue; + if (Array.isArray(value)) { + for (const entry of value){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + continue; } - if (Array.isArray(record.summaries)) { - return record.summaries.some((entry)=>entryMentionsThread(entry, threadId)); + for (const [hostId, entry] of Object.entries(value)){ + const fromEntry = hostNameFromEntry(entry); + if (fromEntry) { + names.set(fromEntry.hostId, fromEntry.hostName); + continue; + } + const label = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (label) names.set(hostId, label); } - return Object.values(record).some((entry)=>entryMentionsThread(entry, threadId)); } - return false; + return names; } - function entryMentionsThread(entry, threadId) { - if (typeof entry === 'string') return entry === threadId; - if (!entry || typeof entry !== 'object') return false; + function hostNameFromEntry(entry) { + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; const row = entry; + const hostId = stringField(row, [ + 'hostId', + 'id', + 'host_id', + 'uuid' + ]); + const hostName = stringField(row, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (!hostId || !hostName) return null; + return { + hostId, + hostName + }; + } + function extractHostName(value) { + if (!value || typeof value !== 'object' || Array.isArray(value)) return null; + return stringField(value, [ + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName' + ]); + } + function extractPinnedIds(value) { + const pinned = new Set(); + if (!value || typeof value !== 'object') return pinned; + const record = value; for (const key of [ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'pinned_ids' + ]){ + const arr = record[key]; + if (!Array.isArray(arr)) continue; + for (const item of arr){ + if (typeof item === 'string' && item) pinned.add(item); + else if (item && typeof item === 'object') { + const id = stringField(item, [ + 'id', + 'threadId', + 'thread_id' + ]); + if (id) pinned.add(id); + } + } + } + return pinned; + } + function extractThreadEntries(value) { + if (Array.isArray(value)) return value; + if (!value || typeof value !== 'object') return []; + const record = value; + for (const key of [ + 'threads', + 'summaries', + 'items', + 'data', + 'conversations' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + const entries = []; + for (const [key, entry] of Object.entries(record)){ + if ([ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName', + 'hostId', + 'version' + ].includes(key)) { + continue; + } + if (typeof entry === 'string') continue; + if (entry && typeof entry === 'object' && !Array.isArray(entry)) { + const row = entry; + if (!stringField(row, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ])) { + entries.push({ + ...row, + id: key + }); + } else { + entries.push(entry); + } + } + } + return entries; + } + function mapRemoteEntry(entry, { hostId, hostName, pinnedIds }) { + if (typeof entry === 'string' && entry) { + return { + threadId: (0, _thread_ids_js__rspack_import_3.BS)(entry), + title: entry, + pinned: pinnedIds.has(entry), + selected: false, + kind: 'remote', + location: 'remote', + hostId, + hostName + }; + } + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + const row = entry; + const id = stringField(row, [ 'id', 'threadId', 'thread_id', 'conversationId' - ]){ - if (row[key] === threadId) return true; + ]); + if (!id) return null; + const title = stringField(row, [ + 'title', + 'name', + 'preview', + 'label' + ]) || id; + const projectId = stringField(row, [ + 'projectId', + 'project_id' + ]); + const project = stringField(row, [ + 'project', + 'projectName', + 'project_name', + 'cwd' + ]) || projectId || undefined; + const preview = stringField(row, [ + 'preview', + 'snippet' + ]); + const cwd = stringField(row, [ + 'cwd', + 'workingDirectory', + 'working_directory' + ]); + const modelProvider = stringField(row, [ + 'modelProvider', + 'model_provider', + 'provider' + ]); + const model = stringField(row, [ + 'model' + ]); + const originator = stringField(row, [ + 'originator', + 'source' + ]); + const createdAt = numberField(row, [ + 'createdAt', + 'created_at' + ]); + const updatedAt = numberField(row, [ + 'updatedAt', + 'updated_at' + ]); + const sectionName = stringField(row, [ + 'sectionName', + 'section' + ]); + const sectionId = stringField(row, [ + 'sectionId', + 'section_id' + ]) || sectionName; + const pinned = pinnedIds.has(id) || row.pinned === true || sectionId === 'Pinned' || sectionName === 'Pinned'; + return { + threadId: (0, _thread_ids_js__rspack_import_3.BS)(id), + title, + pinned, + selected: false, + kind: 'remote', + location: 'remote', + hostId, + hostName, + ...project ? { + project + } : {}, + ...projectId ? { + projectId + } : {}, + ...preview ? { + preview + } : {}, + ...cwd ? { + cwd + } : { + cwd: null + }, + createdAt: createdAt ?? null, + updatedAt: updatedAt ?? null, + ...sectionId ? { + section: { + id: sectionId, + name: sectionName ?? sectionId + } + } : { + section: null + }, + ...modelProvider ? { + modelProvider + } : { + modelProvider: null + }, + ...model ? { + model + } : { + model: null + }, + ...originator ? { + originator + } : { + originator: null + } + }; + } + function stringField(row, keys) { + if (!row || typeof row !== 'object' || Array.isArray(row)) return null; + const record = row; + for (const key of keys){ + const value = record[key]; + if (typeof value === 'string' && value.trim()) return value.trim(); } - return false; + return null; + } + function numberField(row, keys) { + for (const key of keys){ + const value = row[key]; + if (typeof value === 'number' && Number.isFinite(value)) return value; + } + return null; } __webpack_require__.d(__webpack_exports__, { - X: ()=>findRemoteThreadHostId + Hx: ()=>listRemoteThreadsFromState, + KI: ()=>findRemoteThread, + XI: ()=>findRemoteThreadHostId }); }, "./src/core/chatgpt-desktop/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -8108,12 +8585,16 @@ var __webpack_modules__ = { }).strict(); const listThreadsSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), - limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const searchThreadsSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), query: zod__rspack_import_4.YjP().min(1).max(512), - limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50) + limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), @@ -8171,9 +8652,13 @@ var __webpack_modules__ = { code: error.code, error: error.message, threadId: error.threadId, + hint: error.hint, ...error.hostId ? { hostId: error.hostId } : {}, + ...error.hostName ? { + hostName: error.hostName + } : {}, exitCode: 1 }); } @@ -8197,7 +8682,9 @@ var __webpack_modules__ = { async function listThreadsOperation(input) { try { const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ - limit: input.limit + limit: input.limit, + host: input.host, + groupBy: input.groupBy })); return asResult({ ...out, @@ -8215,7 +8702,9 @@ var __webpack_modules__ = { } return adapter.searchThreads({ query: input.query, - limit: input.limit + limit: input.limit, + host: input.host, + groupBy: input.groupBy }); }); return asResult({ @@ -8937,7 +9426,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List ChatGPT Desktop / Codex threads via app-server thread/list (modelProviders:[], useStateDbOnly). Merges CDP-only UI fields (selected, pinned overlay) when CDP is connected. Desktop local: strips to bare app-server ids. Result includes backend.', + description: 'List ChatGPT Desktop / Codex threads: local app-server thread/list (modelProviders:[]) merged with remote-control summaries from ~/.codex/.codex-global-state.json (remote-thread-summaries-v3:). Each thread has location local|remote and hostId/hostName. Optional host filter and groupBy=host. Merges CDP selected when connected. Result includes backend.', annotations: { readOnlyHint: true }, @@ -8953,6 +9442,17 @@ var __webpack_modules__ = { limit: { type: 'number', description: 'Maximum threads (1-200).' + }, + host: { + type: 'string', + description: 'Filter by hostId or friendly host/env name (use "local" for local-only).' + }, + groupBy: { + type: 'string', + enum: [ + 'host' + ], + description: 'When "host", also return groups[] keyed by host.' } }, required: [] @@ -8980,7 +9480,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. DOM harvest/wheel is fallback only when app-server is unavailable. Result includes backend.', + description: 'Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host\'s app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.', annotations: { readOnlyHint: true }, @@ -9039,7 +9539,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop search threads', - description: 'Search ChatGPT Desktop / Codex threads through the local app-server (thread/list with modelProviders:[]), matching name/preview/cwd/project/model fields. Merges CDP selected/pinned when connected. Result includes backend.', + description: 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries in ~/.codex/.codex-global-state.json. Optional host filter and groupBy=host. Merges CDP selected/pinned when connected. Result includes backend.', annotations: { readOnlyHint: true }, @@ -9059,6 +9559,17 @@ var __webpack_modules__ = { limit: { type: 'number', description: 'Maximum matches (1-200).' + }, + host: { + type: 'string', + description: 'Filter by hostId or friendly host/env name (use "local" for local-only).' + }, + groupBy: { + type: 'string', + enum: [ + 'host' + ], + description: 'When "host", also return groups[] keyed by host.' } }, required: [ @@ -58372,10 +58883,21 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "List ChatGPT Desktop / Codex threads via app-server thread/list (modelProviders:[], useStateDbOnly). Merges CDP-only UI fields (selected, pinned overlay) when CDP is connected. Desktop local: strips to bare app-server ids. Result includes backend.", + "description": "List ChatGPT Desktop / Codex threads: local app-server thread/list (modelProviders:[]) merged with remote-control summaries from ~/.codex/.codex-global-state.json (remote-thread-summaries-v3:). Each thread has location local|remote and hostId/hostName. Optional host filter and groupBy=host. Merges CDP selected when connected. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "groupBy": { + "description": "When \"host\", also return groups[] keyed by host.", + "enum": [ + "host" + ], + "type": "string" + }, + "host": { + "description": "Filter by hostId or friendly host/env name (use \"local\" for local-only).", + "type": "string" + }, "limit": { "description": "Maximum threads (1-200).", "type": "number" @@ -58399,7 +58921,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. DOM harvest/wheel is fallback only when app-server is unavailable. Result includes backend.", + "description": "Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -58442,10 +58964,21 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Search ChatGPT Desktop / Codex threads through the local app-server (thread/list with modelProviders:[]), matching name/preview/cwd/project/model fields. Merges CDP selected/pinned when connected. Result includes backend.", + "description": "Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries in ~/.codex/.codex-global-state.json. Optional host filter and groupBy=host. Merges CDP selected/pinned when connected. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "groupBy": { + "description": "When \"host\", also return groups[] keyed by host.", + "enum": [ + "host" + ], + "type": "string" + }, + "host": { + "description": "Filter by hostId or friendly host/env name (use \"local\" for local-only).", + "type": "string" + }, "limit": { "description": "Maximum matches (1-200).", "type": "number" diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index a15927c..2aba9dc 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -88,22 +88,29 @@ Surfaced list fields: `id`, `name`, `preview`, `cwd`, `createdAt` / `projectId`, `status`, `modelProvider`, `model`, `originator`. `archived` is a list filter, not a field. +`chatgpt_desktop_list_threads` merges local app-server threads with +remote-control summaries from `~/.codex/.codex-global-state.json` keys +`remote-thread-summaries-v3:` (title, ids, remote project info; pinned +ids live there too). Every row gets `location: "local" | "remote"` plus +`hostId` / `hostName` when known. Filter with `host` (hostId or friendly name; +`host: "local"` for local-only) and optionally `groupBy: "host"`. + ### Remote-control threads -Threads owned by another host are not loaded locally and return -`thread not loaded`. The adapter raises `RemoteThreadNotLoadedError` and, when -possible, names the owning `hostId` from -`~/.codex/.codex-global-state.json` keys `remote-thread-summaries-v3:`. -SSH remoting is **not** implemented in this PR (follow-up). +Remote rows appear in list/search results. `chatgpt_desktop_read_thread` on a +remote-only thread raises `RemoteThreadNotLoadedError` (`REMOTE_THREAD_NOT_LOADED`) +with `hostId`, optional `hostName`, and a `hint` to read it via that host's +app-server. SSH remoting is **not** implemented in this PR (follow-up). The +global-state parser is defensive — unknown shapes are skipped. ## Backend capability matrix | Operation | CDP | App-server | | --- | --- | --- | | `status` | `/json/version` + attach | daemon probe | -| `list_threads` | merge selected / UI overlay | primary (`thread/list`, all providers) | -| `search_threads` | merge selected when connected | primary (list + filter) | -| `read_thread` | DOM harvest / wheel **fallback only** | primary (`thread/read` + turns/list) | +| `list_threads` | merge selected / UI overlay | primary inventory + remote summaries | +| `search_threads` | merge selected when connected | primary (list + filter, includes remotes) | +| `read_thread` | DOM harvest / wheel **fallback only** (local) | primary; remote → typed error + host hint | | `open_thread` (selected) | click sidebar row | **not used** (resume attaches) | | `send` / new-thread-in-project | composer + Enter / project button | **not used** | | `wait_reply` | Stop gone + final-assistant | **not used** | diff --git a/src/cli/chatgpt-desktop/threads.tsx b/src/cli/chatgpt-desktop/threads.tsx index abec1f0..8922b73 100644 --- a/src/cli/chatgpt-desktop/threads.tsx +++ b/src/cli/chatgpt-desktop/threads.tsx @@ -10,11 +10,13 @@ import { export const config = { description: - 'List ChatGPT Desktop threads via app-server when available; merge CDP pinned/selected/project.', + 'List local + remote-control ChatGPT Desktop threads; optional --host and --group-by host.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, properties: { + groupBy: { description: 'Group results by host', enum: ['host'], type: 'string' }, + host: { description: 'Filter by hostId or friendly name (local for local-only)', type: 'string' }, limit: { default: 50, description: 'Max threads (1-200)', type: 'number' }, port: { description: 'Local CDP port', type: 'number' }, }, @@ -24,6 +26,8 @@ export const config = { export const inputSchema = z .object({ + groupBy: z.literal('host').optional(), + host: z.string().min(1).max(256).optional(), limit: z.number().int().min(1).max(200).default(50), port: z.number().int().min(1).max(65535).optional(), }) @@ -44,10 +48,18 @@ export default async function chatgptDesktopThreads({ title?: string; selected?: boolean; pinned?: boolean; + location?: string; + hostId?: string | null; + hostName?: string | null; }; + const where = + row.location === 'remote' + ? ` [remote ${row.hostName || row.hostId || '?'}]` + : ' [local]'; return ( `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + - (row.pinned ? ' (pinned)' : '') + (row.pinned ? ' (pinned)' : '') + + where ); }) .join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` diff --git a/src/core/chatgpt-desktop/adapter.ts b/src/core/chatgpt-desktop/adapter.ts index f7c6efa..e0bffcd 100644 --- a/src/core/chatgpt-desktop/adapter.ts +++ b/src/core/chatgpt-desktop/adapter.ts @@ -15,11 +15,17 @@ import type { export interface ChatGptDesktopAdapter { connect(options: { port: number }): Promise; listTargets(): Promise; - listThreads(options?: { limit?: number }): Promise; + listThreads(options?: { + limit?: number; + host?: string; + groupBy?: 'host'; + }): Promise; /** Optional; facades that support app-server search implement this. */ searchThreads?(options: { query: string; limit?: number; + host?: string; + groupBy?: 'host'; }): Promise; readThread(options: { threadId: string; diff --git a/src/core/chatgpt-desktop/app-server-fallback.ts b/src/core/chatgpt-desktop/app-server-fallback.ts index 73337a6..78df82a 100644 --- a/src/core/chatgpt-desktop/app-server-fallback.ts +++ b/src/core/chatgpt-desktop/app-server-fallback.ts @@ -17,7 +17,7 @@ import { openCodexSession, } from '../codex-bridge.js'; import { RemoteThreadNotLoadedError } from './errors.js'; -import { findRemoteThreadHostId } from './remote-threads.js'; +import { findRemoteThread, findRemoteThreadHostId } from './remote-threads.js'; import { requireAppServerThreadId, toDesktopThreadId, @@ -90,6 +90,32 @@ export async function appServerReadThread({ }): Promise { // Prefixed `local:` ids fail with `invalid thread id` — always strip first. const bare = requireAppServerThreadId(threadId); + + // Known remote-only threads: fail fast with a typed error + host hint. + const remote = findRemoteThread(bare); + if (remote) { + // Still try local app-server in case the thread was also loaded locally. + try { + return await readLocalThread(bare, { limit, full }); + } catch (error) { + if (isThreadNotLoaded(error) || isUnknownThread(error)) { + throw new RemoteThreadNotLoadedError(bare, remote.hostId, remote.hostName); + } + throw maybeRemoteThreadError(error, bare); + } + } + + try { + return await readLocalThread(bare, { limit, full }); + } catch (error) { + throw maybeRemoteThreadError(error, bare); + } +} + +async function readLocalThread( + bare: string, + { limit, full }: { limit: number; full: boolean }, +): Promise { const { client } = await openCodexSession(); try { const meta = await readThreadMetadata(client, bare); @@ -106,8 +132,6 @@ export async function appServerReadThread({ modelProvider: meta.modelProvider, model: meta.model, }; - } catch (error) { - throw maybeRemoteThreadError(error, bare); } finally { client.close(); } @@ -165,6 +189,9 @@ function mapListedThread(thread: ListedThread): ChatGptDesktopThread { pinned, selected: false, kind: 'codex', + location: 'local', + hostId: null, + hostName: null, preview: typeof thread.preview === 'string' ? thread.preview : undefined, cwd: thread.cwd ?? null, createdAt: thread.createdAt ?? null, @@ -413,11 +440,20 @@ function isThreadNotLoaded(error: unknown): boolean { return /thread not loaded|not loaded|invalid thread id/i.test(message); } +function isUnknownThread(error: unknown): boolean { + const message = errorMessage(error); + return /no rollout found|thread not found|unknown.*thread/i.test(message); +} + function maybeRemoteThreadError(error: unknown, threadId: string): Error { const message = errorMessage(error); - if (/thread not loaded|not loaded/i.test(message)) { + if (/thread not loaded|not loaded|no rollout found|thread not found/i.test(message)) { + const remote = findRemoteThread(threadId); + if (remote) { + return new RemoteThreadNotLoadedError(threadId, remote.hostId, remote.hostName); + } const hostId = findRemoteThreadHostId(threadId); - return new RemoteThreadNotLoadedError(threadId, hostId); + return new RemoteThreadNotLoadedError(threadId, hostId, null); } if (error instanceof Error) return error; return new Error(message || `app-server error for thread ${threadId}`); diff --git a/src/core/chatgpt-desktop/errors.ts b/src/core/chatgpt-desktop/errors.ts index c657443..6346f79 100644 --- a/src/core/chatgpt-desktop/errors.ts +++ b/src/core/chatgpt-desktop/errors.ts @@ -43,7 +43,8 @@ export class CdpUnreachableError extends Error { /** * Thread exists on a remote-control host and is not loaded on the local - * app-server. SSH remoting is a follow-up — this error only names the owner. + * app-server. SSH remoting is a follow-up — this error names the owner and + * tells the caller to read via that host's app-server. */ export class RemoteThreadNotLoadedError extends Error { readonly code = 'REMOTE_THREAD_NOT_LOADED' as const; @@ -51,17 +52,34 @@ export class RemoteThreadNotLoadedError extends Error { readonly reason = 'remote-thread-not-loaded' as const; readonly threadId: string; readonly hostId: string | null; + readonly hostName: string | null; + readonly hint: string; - constructor(threadId: string, hostId: string | null = null) { - const owner = hostId - ? `owned by remote-control host ${JSON.stringify(hostId)}` + constructor( + threadId: string, + hostId: string | null = null, + hostName: string | null = null, + ) { + const hostLabel = hostName + ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` + : hostId + ? JSON.stringify(hostId) + : null; + const owner = hostLabel + ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + const hint = hostId + ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + + (hostName ? ` (${hostName})` : '') + + '. SSH remoting is not implemented in this adapter.' + : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; super( - `Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ` + - `${owner}. SSH remoting is not implemented in this adapter yet.`, + `Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`, ); this.name = 'RemoteThreadNotLoadedError'; this.threadId = threadId; this.hostId = hostId; + this.hostName = hostName; + this.hint = hint; } } diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index 1c3b611..899735a 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -6,14 +6,16 @@ import { appServerSearchThreads, appServerStatusProbe, } from './app-server-fallback.js'; -import { CdpUnreachableError, NotImplementedError } from './errors.js'; +import { CdpUnreachableError, NotImplementedError, RemoteThreadNotLoadedError } from './errors.js'; import { resolveCdpPort } from './loopback.js'; +import { listRemoteThreadsFromState } from './remote-threads.js'; import { isTemporaryDesktopThreadId, threadIdsEquivalent, toAppServerThreadId, } from './thread-ids.js'; import type { + ChatGptDesktopHostGroup, ChatGptDesktopStatus, ChatGptDesktopTarget, ChatGptDesktopThread, @@ -30,6 +32,7 @@ export type ChatGptDesktopFallbacks = { searchThreads: typeof appServerSearchThreads; readThread: typeof appServerReadThread; statusProbe: typeof appServerStatusProbe; + listRemoteThreads?: typeof listRemoteThreadsFromState; }; const defaultFallbacks: ChatGptDesktopFallbacks = { @@ -37,17 +40,24 @@ const defaultFallbacks: ChatGptDesktopFallbacks = { searchThreads: appServerSearchThreads, readThread: appServerReadThread, statusProbe: appServerStatusProbe, + listRemoteThreads: listRemoteThreadsFromState, +}; + +export type ListThreadsOptions = { + limit?: number; + /** Filter by remote hostId or friendly host/env name (substring, case-insensitive). */ + host?: string; + /** When `"host"`, also return `groups` keyed by host. */ + groupBy?: 'host'; }; /** * ChatGPT Desktop facade (verified against app-server 0.158.0). * - * - List / search / read: app-server primary (`thread/list`, `thread/read` + - * `thread/turns/list`). DOM read is fallback only when app-server is unavailable. + * - List / search / read: app-server primary; list also merges remote-control + * summaries from `~/.codex/.codex-global-state.json`. * - Send, new-thread-in-project, wait-for-reply, selected thread / UI state: CDP. * - Every list/read/send/wait/open result reports `backend: "cdp" | "app-server"`. - * - * Reuses the existing Codex app-server client — never duplicates that JSON-RPC stack. */ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { #cdp: ChatGptDesktopAdapter; @@ -81,11 +91,12 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { return this.#cdp.listTargets(); } - async listThreads(options?: { limit?: number }): Promise { + async listThreads(options: ListThreadsOptions = {}): Promise { + const limit = options.limit ?? 50; let appList: ListThreadsResult | null = null; let appError: unknown; try { - appList = await this.#fallbacks.listThreads(options); + appList = await this.#fallbacks.listThreads({ limit }); } catch (error) { appError = error; } @@ -94,7 +105,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { let cdpError: unknown; try { await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads(options); + cdpList = await this.#cdp.listThreads({ limit }); } catch (error) { if (isCdpFailure(error)) { this.#cdpConnected = false; @@ -103,38 +114,68 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { } } - if (appList && cdpList) { - return mergeThreadLists(appList, cdpList); - } - if (appList) return appList; - if (cdpList) return cdpList; - if (cdpError) throw cdpError; - if (appError) throw appError; - throw new CdpUnreachableError('ChatGPT Desktop listThreads: CDP and app-server unreachable'); + let base: ListThreadsResult | null = null; + if (appList && cdpList) base = mergeThreadLists(appList, cdpList); + else if (appList) base = appList; + else if (cdpList) base = cdpList; + else if (cdpError) throw cdpError; + else if (appError) throw appError; + else throw new CdpUnreachableError('ChatGPT Desktop listThreads: CDP and app-server unreachable'); + + return finalizeThreadList(base, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: this.#listRemotes(), + }); } async searchThreads(options: { query: string; limit?: number; + host?: string; + groupBy?: 'host'; }): Promise { + const limit = options.limit ?? 50; try { - const appList = await this.#fallbacks.searchThreads(options); - const cdpList = await this.#tryCdpList({ limit: options.limit }); - if (cdpList) return mergeThreadLists(appList, cdpList); - return appList; + const appList = await this.#fallbacks.searchThreads({ + query: options.query, + limit, + }); + const cdpList = await this.#tryCdpList({ limit }); + const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const withRemotes = finalizeThreadList(base, { + limit: 10_000, + host: options.host, + remotes: this.#listRemotes(), + }); + const needle = options.query.trim().toLowerCase(); + const filtered = { + ...withRemotes, + query: options.query, + threads: withRemotes.threads.filter((thread) => threadMatchesQuery(thread, needle)), + }; + return finalizeThreadList(filtered, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: [], + }); } catch (appError) { - const cdpList = await this.#tryCdpList({ limit: options.limit }); + const cdpList = await this.#tryCdpList({ limit }); if (!cdpList) throw appError; const needle = options.query.trim().toLowerCase(); - return { + const filtered = { ...cdpList, query: options.query, - threads: cdpList.threads.filter((thread) => { - if (!needle) return true; - return [thread.title, thread.threadId, thread.project] - .some((value) => typeof value === 'string' && value.toLowerCase().includes(needle)); - }), + threads: cdpList.threads.filter((thread) => threadMatchesQuery(thread, needle)), }; + return finalizeThreadList(filtered, { + limit, + host: options.host, + groupBy: options.groupBy, + remotes: this.#listRemotes(), + }); } } @@ -147,13 +188,11 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { const limit = options.limit ?? 100; const full = options.full ?? false; - // Temporary sidebar rows have no app-server mapping — CDP only. if (isTemporaryDesktopThreadId(options.threadId)) { await this.#ensureCdp(); return this.#cdp.readThread({ ...options, limit, full }); } - // App-server is primary for all durable reads. try { return await this.#fallbacks.readThread({ threadId: options.threadId, @@ -161,7 +200,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { full, }); } catch (appError) { - // DOM harvest / wheel crawl only when app-server is unavailable. + if (appError instanceof RemoteThreadNotLoadedError) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; return this.#cdp.readThread({ ...options, limit, full: full || true }); @@ -190,7 +229,6 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { threadId: string, options?: { openTimeoutMs?: number }, ): Promise { - // Selected-thread / UI focus stays on CDP — do not thread/resume for this. await this.#ensureCdp(); return this.#cdp.openThread(threadId, options); } @@ -223,6 +261,15 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { await this.#cdp.close(); } + #listRemotes() { + const list = this.#fallbacks.listRemoteThreads ?? listRemoteThreadsFromState; + try { + return list(); + } catch { + return []; + } + } + async #ensureCdp(): Promise { if (this.#cdpConnected) return; await this.#cdp.connect({ port: this.#port }); @@ -268,30 +315,135 @@ export function mergeThreadLists( const merged: ChatGptDesktopThread[] = appList.threads.map((thread) => { const key = toAppServerThreadId(thread.threadId) ?? thread.threadId; const cdp = cdpByKey.get(key); - if (!cdp) return thread; - return { + const withLocal: ChatGptDesktopThread = { ...thread, - title: thread.title || cdp.title, - pinned: thread.pinned || cdp.pinned, + location: thread.location ?? 'local', + hostId: thread.hostId ?? null, + hostName: thread.hostName ?? null, + }; + if (!cdp) return withLocal; + return { + ...withLocal, + title: withLocal.title || cdp.title, + pinned: withLocal.pinned || cdp.pinned, selected: cdp.selected, - kind: cdp.kind || thread.kind, - project: cdp.project ?? thread.project, + kind: cdp.kind || withLocal.kind, + project: cdp.project ?? withLocal.project, }; }); - // Keep CDP-only rows (e.g. temporary local:client-new-thread:…) visible. for (const thread of cdpList.threads) { if (merged.some((row) => threadIdsEquivalent(row.threadId, thread.threadId))) continue; - merged.push(thread); + merged.push({ + ...thread, + location: thread.location ?? 'local', + hostId: thread.hostId ?? null, + hostName: thread.hostName ?? null, + }); } return { - backend: 'app-server', + backend: appList.backend, limit: appList.limit, nextCursor: appList.nextCursor, ...(appList.query !== undefined ? { query: appList.query } : {}), - threads: merged.slice(0, appList.limit), + threads: merged, + }; +} + +/** Append remote-control summaries, apply host filter / groupBy / limit. */ +export function finalizeThreadList( + base: ListThreadsResult, + { + limit, + host, + groupBy, + remotes, + }: { + limit: number; + host?: string; + groupBy?: 'host'; + remotes: readonly ChatGptDesktopThread[]; + }, +): ListThreadsResult { + const locals = base.threads.map((thread) => { + const location = thread.location ?? ('local' as const); + return { + ...thread, + location, + hostId: location === 'remote' ? thread.hostId ?? null : null, + hostName: location === 'remote' ? thread.hostName ?? null : null, + }; + }); + + const localKeys = new Set( + locals.map((thread) => toAppServerThreadId(thread.threadId) ?? thread.threadId), + ); + const merged: ChatGptDesktopThread[] = [...locals]; + for (const remote of remotes) { + const key = toAppServerThreadId(remote.threadId) ?? remote.threadId; + if (localKeys.has(key)) continue; + merged.push({ + ...remote, + location: remote.location ?? 'remote', + hostId: remote.hostId ?? null, + hostName: remote.hostName ?? null, + }); + } + + const filtered = host + ? merged.filter((thread) => hostMatches(thread, host)) + : merged; + const limited = filtered.slice(0, limit); + const result: ListThreadsResult = { + backend: base.backend, + limit, + threads: limited, + ...(base.nextCursor !== undefined ? { nextCursor: base.nextCursor } : {}), + ...(base.query !== undefined ? { query: base.query } : {}), + ...(host ? { host } : {}), }; + if (groupBy === 'host') { + return { ...result, groupBy: 'host', groups: groupThreadsByHost(limited) }; + } + return result; +} + +export function groupThreadsByHost( + threads: readonly ChatGptDesktopThread[], +): ChatGptDesktopHostGroup[] { + const groups = new Map(); + for (const thread of threads) { + const location = thread.location ?? 'local'; + const hostId = location === 'remote' ? thread.hostId || 'unknown-remote' : 'local'; + const key = `${location}:${hostId}`; + const existing = groups.get(key); + if (existing) { + (existing.threads as ChatGptDesktopThread[]).push(thread); + continue; + } + groups.set(key, { + hostId, + hostName: thread.hostName ?? (location === 'local' ? 'local' : null), + location, + threads: [thread], + }); + } + return [...groups.values()]; +} + +function hostMatches(thread: ChatGptDesktopThread, host: string): boolean { + const needle = host.trim().toLowerCase(); + if (!needle) return true; + if (needle === 'local') return (thread.location ?? 'local') === 'local'; + return [thread.hostId, thread.hostName] + .some((value) => typeof value === 'string' && value.toLowerCase().includes(needle)); +} + +function threadMatchesQuery(thread: ChatGptDesktopThread, needle: string): boolean { + if (!needle) return true; + return [thread.title, thread.threadId, thread.project, thread.preview, thread.hostName, thread.hostId] + .some((value) => typeof value === 'string' && value.toLowerCase().includes(needle)); } function isCdpFailure(error: unknown): boolean { diff --git a/src/core/chatgpt-desktop/index.ts b/src/core/chatgpt-desktop/index.ts index bb2bc87..be78682 100644 --- a/src/core/chatgpt-desktop/index.ts +++ b/src/core/chatgpt-desktop/index.ts @@ -27,11 +27,13 @@ export { } from './errors.js'; export { ChatGptDesktopFacade, + finalizeThreadList, getChatGptDesktopAdapter, + groupThreadsByHost, mergeThreadLists, setChatGptDesktopAdapterForTests, } from './facade.js'; -export type { ChatGptDesktopFallbacks } from './facade.js'; +export type { ChatGptDesktopFallbacks, ListThreadsOptions } from './facade.js'; export { HISTORY_CONTENT_TURN_PREFIX, LOCAL_THREAD_ID_PREFIX, @@ -45,7 +47,10 @@ export { } from './thread-ids.js'; export { codexGlobalStatePath, + findRemoteThread, findRemoteThreadHostId, + listRemoteThreadsFromState, + loadCodexGlobalState, } from './remote-threads.js'; export { CDP_LOOPBACK_HOST, @@ -81,9 +86,11 @@ export { } from './routes.js'; export type { ChatGptDesktopBackend, + ChatGptDesktopHostGroup, ChatGptDesktopStatus, ChatGptDesktopTarget, ChatGptDesktopThread, + ChatGptDesktopThreadLocation, ChatGptDesktopThreadSection, ChatGptDesktopTurn, ListThreadsResult, diff --git a/src/core/chatgpt-desktop/remote-threads.ts b/src/core/chatgpt-desktop/remote-threads.ts index d347824..2976296 100644 --- a/src/core/chatgpt-desktop/remote-threads.ts +++ b/src/core/chatgpt-desktop/remote-threads.ts @@ -1,75 +1,312 @@ /** - * Look up which remote-control host owns a Codex thread that is not loaded - * locally. Reads `~/.codex/.codex-global-state.json` keys shaped like - * `remote-thread-summaries-v3:`. SSH remoting is intentionally not - * implemented here — follow-up work. + * Remote-control thread summaries from ChatGPT Desktop's + * `~/.codex/.codex-global-state.json`. + * + * Keys are shaped like `remote-thread-summaries-v3:` and may hold + * titles, ids, remote project info, and pinned ids. The file is app-internal + * and may change — parse defensively and ignore unknown shapes. + * + * SSH remoting is intentionally not implemented here (follow-up). */ import { readFileSync } from 'node:fs'; import { homedir } from 'node:os'; import { join } from 'node:path'; -import { toAppServerThreadId } from './thread-ids.js'; +import { toAppServerThreadId, toDesktopThreadId } from './thread-ids.js'; +import type { ChatGptDesktopThread } from './types.js'; const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; +export type RemoteHostInfo = { + readonly hostId: string; + readonly hostName: string | null; +}; + +export type RemoteThreadRecord = ChatGptDesktopThread & { + readonly location: 'remote'; + readonly hostId: string; + readonly hostName: string | null; +}; + +export type RemoteThreadLookup = { + readonly hostId: string; + readonly hostName: string | null; + readonly thread: RemoteThreadRecord | null; +}; + export function codexGlobalStatePath(env: NodeJS.ProcessEnv = process.env): string { const home = env.CODEX_HOME || join(homedir(), '.codex'); return join(home, '.codex-global-state.json'); } -/** Best-effort hostId for a thread listed under a remote-control summary. */ -export function findRemoteThreadHostId( - threadId: string, +/** Read and JSON-parse the Desktop global state file; null when missing/invalid. */ +export function loadCodexGlobalState( env: NodeJS.ProcessEnv = process.env, -): string | null { - const bare = toAppServerThreadId(threadId) ?? threadId; - if (!bare) return null; +): Record | null { let raw: string; try { raw = readFileSync(codexGlobalStatePath(env), 'utf8'); } catch { return null; } - let data: unknown; try { - data = JSON.parse(raw); + const data = JSON.parse(raw) as unknown; + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + return data as Record; } catch { return null; } - if (!data || typeof data !== 'object' || Array.isArray(data)) return null; - for (const [key, value] of Object.entries(data as Record)) { +} + +/** + * Parse every `remote-thread-summaries-v3:` entry into flat remote + * thread rows. Unknown/malformed entries are skipped. + */ +export function listRemoteThreadsFromState( + env: NodeJS.ProcessEnv = process.env, +): RemoteThreadRecord[] { + const data = loadCodexGlobalState(env); + if (!data) return []; + const hostNames = collectHostNames(data); + const out: RemoteThreadRecord[] = []; + const seen = new Set(); + + for (const [key, value] of Object.entries(data)) { const match = REMOTE_SUMMARY_KEY.exec(key); - if (!match) continue; - if (summariesIncludeThread(value, bare)) return match[1] ?? null; + if (!match?.[1]) continue; + const hostId = match[1]; + const hostName = hostNames.get(hostId) ?? extractHostName(value); + const pinnedIds = extractPinnedIds(value); + for (const entry of extractThreadEntries(value)) { + const mapped = mapRemoteEntry(entry, { hostId, hostName, pinnedIds }); + if (!mapped) continue; + const bare = toAppServerThreadId(mapped.threadId) ?? mapped.threadId; + const dedupe = `${hostId}:${bare}`; + if (seen.has(dedupe)) continue; + seen.add(dedupe); + out.push(mapped); + } + } + return out; +} + +/** Best-effort hostId (+ optional summary row) for a thread under remote summaries. */ +export function findRemoteThread( + threadId: string, + env: NodeJS.ProcessEnv = process.env, +): RemoteThreadLookup | null { + const bare = toAppServerThreadId(threadId) ?? threadId; + if (!bare) return null; + for (const thread of listRemoteThreadsFromState(env)) { + const id = toAppServerThreadId(thread.threadId) ?? thread.threadId; + if (id === bare) { + return { hostId: thread.hostId, hostName: thread.hostName, thread }; + } } return null; } -function summariesIncludeThread(value: unknown, threadId: string): boolean { - if (Array.isArray(value)) { - return value.some((entry) => entryMentionsThread(entry, threadId)); +/** Best-effort hostId for a thread listed under a remote-control summary. */ +export function findRemoteThreadHostId( + threadId: string, + env: NodeJS.ProcessEnv = process.env, +): string | null { + return findRemoteThread(threadId, env)?.hostId ?? null; +} + +function collectHostNames(data: Record): Map { + const names = new Map(); + for (const [key, value] of Object.entries(data)) { + if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; + if (!value || typeof value !== 'object') continue; + if (Array.isArray(value)) { + for (const entry of value) { + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + continue; + } + for (const [hostId, entry] of Object.entries(value as Record)) { + const fromEntry = hostNameFromEntry(entry); + if (fromEntry) { + names.set(fromEntry.hostId, fromEntry.hostName); + continue; + } + const label = stringField(entry, ['name', 'hostName', 'displayName', 'envName', 'label', 'title']); + if (label) names.set(hostId, label); + } } - if (value && typeof value === 'object') { - const record = value as Record; - if (threadId in record) return true; - if (Array.isArray(record.threads)) { - return record.threads.some((entry) => entryMentionsThread(entry, threadId)); + return names; +} + +function hostNameFromEntry(entry: unknown): { hostId: string; hostName: string } | null { + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + const row = entry as Record; + const hostId = stringField(row, ['hostId', 'id', 'host_id', 'uuid']); + const hostName = stringField(row, ['name', 'hostName', 'displayName', 'envName', 'label', 'title']); + if (!hostId || !hostName) return null; + return { hostId, hostName }; +} + +function extractHostName(value: unknown): string | null { + if (!value || typeof value !== 'object' || Array.isArray(value)) return null; + return stringField(value as Record, [ + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName', + ]); +} + +function extractPinnedIds(value: unknown): Set { + const pinned = new Set(); + if (!value || typeof value !== 'object') return pinned; + const record = value as Record; + for (const key of ['pinnedIds', 'pinned', 'pinnedThreadIds', 'pinned_ids']) { + const arr = record[key]; + if (!Array.isArray(arr)) continue; + for (const item of arr) { + if (typeof item === 'string' && item) pinned.add(item); + else if (item && typeof item === 'object') { + const id = stringField(item as Record, ['id', 'threadId', 'thread_id']); + if (id) pinned.add(id); + } } - if (Array.isArray(record.summaries)) { - return record.summaries.some((entry) => entryMentionsThread(entry, threadId)); + } + return pinned; +} + +function extractThreadEntries(value: unknown): unknown[] { + if (Array.isArray(value)) return value; + if (!value || typeof value !== 'object') return []; + const record = value as Record; + for (const key of ['threads', 'summaries', 'items', 'data', 'conversations']) { + if (Array.isArray(record[key])) return record[key] as unknown[]; + } + // Object map keyed by thread id → treat values (and string keys) as entries. + const entries: unknown[] = []; + for (const [key, entry] of Object.entries(record)) { + if ( + [ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName', + 'hostId', + 'version', + ].includes(key) + ) { + continue; + } + if (typeof entry === 'string') continue; + if (entry && typeof entry === 'object' && !Array.isArray(entry)) { + const row = entry as Record; + if (!stringField(row, ['id', 'threadId', 'thread_id', 'conversationId'])) { + entries.push({ ...row, id: key }); + } else { + entries.push(entry); + } } - return Object.values(record).some((entry) => entryMentionsThread(entry, threadId)); } - return false; + return entries; } -function entryMentionsThread(entry: unknown, threadId: string): boolean { - if (typeof entry === 'string') return entry === threadId; - if (!entry || typeof entry !== 'object') return false; +function mapRemoteEntry( + entry: unknown, + { + hostId, + hostName, + pinnedIds, + }: { + hostId: string; + hostName: string | null; + pinnedIds: Set; + }, +): RemoteThreadRecord | null { + if (typeof entry === 'string' && entry) { + return { + threadId: toDesktopThreadId(entry), + title: entry, + pinned: pinnedIds.has(entry), + selected: false, + kind: 'remote', + location: 'remote', + hostId, + hostName, + }; + } + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; const row = entry as Record; - for (const key of ['id', 'threadId', 'thread_id', 'conversationId']) { - if (row[key] === threadId) return true; + const id = stringField(row, ['id', 'threadId', 'thread_id', 'conversationId']); + if (!id) return null; + const title = + stringField(row, ['title', 'name', 'preview', 'label']) || id; + const projectId = stringField(row, ['projectId', 'project_id']); + const project = + stringField(row, ['project', 'projectName', 'project_name', 'cwd']) || projectId || undefined; + const preview = stringField(row, ['preview', 'snippet']); + const cwd = stringField(row, ['cwd', 'workingDirectory', 'working_directory']); + const modelProvider = stringField(row, ['modelProvider', 'model_provider', 'provider']); + const model = stringField(row, ['model']); + const originator = stringField(row, ['originator', 'source']); + const createdAt = numberField(row, ['createdAt', 'created_at']); + const updatedAt = numberField(row, ['updatedAt', 'updated_at']); + const sectionName = stringField(row, ['sectionName', 'section']); + const sectionId = stringField(row, ['sectionId', 'section_id']) || sectionName; + const pinned = + pinnedIds.has(id) || + row.pinned === true || + sectionId === 'Pinned' || + sectionName === 'Pinned'; + + return { + threadId: toDesktopThreadId(id), + title, + pinned, + selected: false, + kind: 'remote', + location: 'remote', + hostId, + hostName, + ...(project ? { project } : {}), + ...(projectId ? { projectId } : {}), + ...(preview ? { preview } : {}), + ...(cwd ? { cwd } : { cwd: null }), + createdAt: createdAt ?? null, + updatedAt: updatedAt ?? null, + ...(sectionId + ? { section: { id: sectionId, name: sectionName ?? sectionId } } + : { section: null }), + ...(modelProvider ? { modelProvider } : { modelProvider: null }), + ...(model ? { model } : { model: null }), + ...(originator ? { originator } : { originator: null }), + }; +} + +function stringField(row: Record | unknown, keys: string[]): string | null { + if (!row || typeof row !== 'object' || Array.isArray(row)) return null; + const record = row as Record; + for (const key of keys) { + const value = record[key]; + if (typeof value === 'string' && value.trim()) return value.trim(); + } + return null; +} + +function numberField(row: Record, keys: string[]): number | null { + for (const key of keys) { + const value = row[key]; + if (typeof value === 'number' && Number.isFinite(value)) return value; } - return false; + return null; } diff --git a/src/core/chatgpt-desktop/routes.ts b/src/core/chatgpt-desktop/routes.ts index b5514f5..f1a0888 100644 --- a/src/core/chatgpt-desktop/routes.ts +++ b/src/core/chatgpt-desktop/routes.ts @@ -17,6 +17,8 @@ export const listThreadsSchema = z .object({ port: z.number().int().min(1).max(65535).optional(), limit: z.number().int().min(1).max(200).default(50), + host: z.string().min(1).max(256).optional(), + groupBy: z.literal('host').optional(), }) .strict(); @@ -25,6 +27,8 @@ export const searchThreadsSchema = z port: z.number().int().min(1).max(65535).optional(), query: z.string().min(1).max(512), limit: z.number().int().min(1).max(200).default(50), + host: z.string().min(1).max(256).optional(), + groupBy: z.literal('host').optional(), }) .strict(); @@ -102,7 +106,9 @@ function mapError(error: unknown): OperationResult { code: error.code, error: error.message, threadId: error.threadId, + hint: error.hint, ...(error.hostId ? { hostId: error.hostId } : {}), + ...(error.hostName ? { hostName: error.hostName } : {}), exitCode: 1 as const, }); } @@ -127,7 +133,11 @@ export async function listThreadsOperation( ): Promise { try { const out = await withAdapter(input.port, (adapter) => - adapter.listThreads({ limit: input.limit }), + adapter.listThreads({ + limit: input.limit, + host: input.host, + groupBy: input.groupBy, + }), ); return asResult({ ...out, exitCode: 0 as const }); } catch (error) { @@ -143,7 +153,12 @@ export async function searchThreadsOperation( if (typeof adapter.searchThreads !== 'function') { throw new NotImplementedError('searchThreads', 'adapter does not implement search'); } - return adapter.searchThreads({ query: input.query, limit: input.limit }); + return adapter.searchThreads({ + query: input.query, + limit: input.limit, + host: input.host, + groupBy: input.groupBy, + }); }); return asResult({ ...out, exitCode: 0 as const }); } catch (error) { diff --git a/src/core/chatgpt-desktop/types.ts b/src/core/chatgpt-desktop/types.ts index 718d7b7..b8a1f2b 100644 --- a/src/core/chatgpt-desktop/types.ts +++ b/src/core/chatgpt-desktop/types.ts @@ -8,6 +8,8 @@ export type ChatGptDesktopTarget = { readonly attached: boolean; }; +export type ChatGptDesktopThreadLocation = 'local' | 'remote'; + export type ChatGptDesktopThreadSection = { readonly id: string; readonly name: string | null; @@ -32,6 +34,19 @@ export type ChatGptDesktopThread = { readonly modelProvider?: string | null; readonly model?: string | null; readonly originator?: string | null; + /** Whether the thread is on the local app-server or a remote-control host. */ + readonly location?: ChatGptDesktopThreadLocation; + /** Remote-control host id when `location` is `remote`; null for local. */ + readonly hostId?: string | null; + /** Friendly host / env name from Desktop global state when known. */ + readonly hostName?: string | null; +}; + +export type ChatGptDesktopHostGroup = { + readonly hostId: string; + readonly hostName: string | null; + readonly location: ChatGptDesktopThreadLocation; + readonly threads: readonly ChatGptDesktopThread[]; }; export type ChatGptDesktopTurn = { @@ -71,6 +86,11 @@ export type ListThreadsResult = { readonly limit: number; readonly nextCursor?: string | null; readonly query?: string; + /** Host filter applied (`hostId` or friendly name substring). */ + readonly host?: string; + readonly groupBy?: 'host'; + /** Present when `groupBy: "host"`. */ + readonly groups?: readonly ChatGptDesktopHostGroup[]; }; export type ReadThreadResult = { diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx index 44e006d..d8a2085 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list threads', description: - 'List ChatGPT Desktop / Codex threads via app-server thread/list (modelProviders:[], useStateDbOnly). Merges CDP-only UI fields (selected, pinned overlay) when CDP is connected. Desktop local: strips to bare app-server ids. Result includes backend.', + 'List ChatGPT Desktop / Codex threads: local app-server thread/list (modelProviders:[]) merged with remote-control summaries from ~/.codex/.codex-global-state.json (remote-thread-summaries-v3:). Each thread has location local|remote and hostId/hostName. Optional host filter and groupBy=host. Merges CDP selected when connected. Result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -23,6 +23,15 @@ export default defineTool( properties: { port: { type: 'number' }, limit: { type: 'number', description: 'Maximum threads (1-200).' }, + host: { + type: 'string', + description: 'Filter by hostId or friendly host/env name (use "local" for local-only).', + }, + groupBy: { + type: 'string', + enum: ['host'], + description: 'When "host", also return groups[] keyed by host.', + }, }, required: [], }, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx index f736690..40578dd 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop read thread', description: - 'Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. DOM harvest/wheel is fallback only when app-server is unavailable. Result includes backend.', + 'Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host\'s app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx index 74be9c0..662a07f 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop search threads', description: - 'Search ChatGPT Desktop / Codex threads through the local app-server (thread/list with modelProviders:[]), matching name/preview/cwd/project/model fields. Merges CDP selected/pinned when connected. Result includes backend.', + 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries in ~/.codex/.codex-global-state.json. Optional host filter and groupBy=host. Merges CDP selected/pinned when connected. Result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -24,6 +24,15 @@ export default defineTool( port: { type: 'number' }, query: { type: 'string', description: 'Case-insensitive substring over thread metadata.' }, limit: { type: 'number', description: 'Maximum matches (1-200).' }, + host: { + type: 'string', + description: 'Filter by hostId or friendly host/env name (use "local" for local-only).', + }, + groupBy: { + type: 'string', + enum: ['host'], + description: 'When "host", also return groups[] keyed by host.', + }, }, required: ['query'], }, diff --git a/tests/fixtures/codex-global-state-remote.json b/tests/fixtures/codex-global-state-remote.json new file mode 100644 index 0000000..6184382 --- /dev/null +++ b/tests/fixtures/codex-global-state-remote.json @@ -0,0 +1,56 @@ +{ + "remote-hosts-v1": { + "host-macbook": { + "name": "Zack's MacBook", + "envName": "desktop" + }, + "host-linux": { + "name": "build-box", + "envName": "ci" + } + }, + "remote-thread-summaries-v3:host-macbook": { + "hostName": "Zack's MacBook", + "pinnedIds": [ + "aaaa1111-1111-1111-1111-111111111111" + ], + "threads": [ + { + "id": "aaaa1111-1111-1111-1111-111111111111", + "title": "Pinned remote chat", + "projectId": "proj-launch", + "projectName": "Launch", + "updatedAt": 1700000100, + "createdAt": 1700000000, + "modelProvider": "openai", + "model": "gpt-5" + }, + { + "id": "bbbb2222-2222-2222-2222-222222222222", + "name": "Remote work thread", + "preview": "hello from remote", + "projectId": "proj-ops", + "updatedAt": 1700000200 + } + ] + }, + "remote-thread-summaries-v3:host-linux": [ + { + "id": "cccc3333-3333-3333-3333-333333333333", + "title": "Linux CI thread", + "project": "Infra", + "updatedAt": 1700000300 + } + ], + "unrelated-key": { + "should": "be ignored" + }, + "remote-thread-summaries-v3:broken-host": { + "threads": [ + { + "title": "missing id should be skipped" + }, + "dddd4444-4444-4444-4444-444444444444" + ] + } +} diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index de602a2..ae4c9b5 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -466,6 +466,7 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () }; }, statusProbe: async () => ({ reachable: true, mode: 'daemon', socketPath: '/tmp/fake.sock' }), + listRemoteThreads: () => [], }); it('lists/searches/reads via app-server (merged with CDP), keeps send/wait/open on CDP', async () => { @@ -752,26 +753,143 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () }); }); - it('surfaces RemoteThreadNotLoadedError with hostId from global state', async () => { - const { mkdtempSync, writeFileSync } = await import('node:fs'); + it('merges remote-control summaries from the global-state fixture', async () => { + const { copyFileSync, mkdtempSync } = await import('node:fs'); const { tmpdir } = await import('node:os'); const { join } = await import('node:path'); - const { RemoteThreadNotLoadedError, findRemoteThreadHostId } = await import( - '../../src/core/chatgpt-desktop/index.js' - ); - const home = mkdtempSync(join(tmpdir(), 'gbot-remote-')); - writeFileSync( + const { + finalizeThreadList, + findRemoteThread, + listRemoteThreadsFromState, + RemoteThreadNotLoadedError, + } = await import('../../src/core/chatgpt-desktop/index.js'); + + const home = mkdtempSync(join(tmpdir(), 'gbot-remote-fix-')); + copyFileSync( + join(process.cwd(), 'tests/fixtures/codex-global-state-remote.json'), join(home, '.codex-global-state.json'), - JSON.stringify({ - 'remote-thread-summaries-v3:host-abc': [{ id: 'remote-thread-1' }], - }), ); - expect(findRemoteThreadHostId('remote-thread-1', { CODEX_HOME: home })).toBe('host-abc'); - expect(findRemoteThreadHostId('local:remote-thread-1', { CODEX_HOME: home })).toBe('host-abc'); - const err = new RemoteThreadNotLoadedError('remote-thread-1', 'host-abc'); + const env = { CODEX_HOME: home }; + const remotes = listRemoteThreadsFromState(env); + expect(remotes.map((t) => t.threadId).sort()).toEqual([ + 'local:aaaa1111-1111-1111-1111-111111111111', + 'local:bbbb2222-2222-2222-2222-222222222222', + 'local:cccc3333-3333-3333-3333-333333333333', + 'local:dddd4444-4444-4444-4444-444444444444', + ]); + const pinned = remotes.find((t) => t.threadId.includes('aaaa1111')); + expect(pinned).toMatchObject({ + location: 'remote', + hostId: 'host-macbook', + hostName: "Zack's MacBook", + pinned: true, + project: 'Launch', + projectId: 'proj-launch', + }); + const linux = remotes.find((t) => t.threadId.includes('cccc3333')); + expect(linux).toMatchObject({ + location: 'remote', + hostId: 'host-linux', + hostName: 'build-box', + project: 'Infra', + }); + + const listed = finalizeThreadList( + { + backend: 'app-server', + limit: 50, + threads: [ + { + threadId: 'local:local-thread-1', + title: 'Local only', + pinned: false, + selected: true, + kind: 'codex', + location: 'local', + hostId: null, + hostName: null, + }, + ], + }, + { limit: 50, remotes, groupBy: 'host' }, + ); + expect(listed.threads.some((t) => t.location === 'local')).toBe(true); + expect(listed.threads.some((t) => t.location === 'remote')).toBe(true); + expect(listed.groups?.map((g) => g.hostId).sort()).toEqual([ + 'broken-host', + 'host-linux', + 'host-macbook', + 'local', + ]); + + const filtered = finalizeThreadList( + { + backend: 'app-server', + limit: 50, + threads: [ + { + threadId: 'local:local-thread-1', + title: 'Local only', + pinned: false, + selected: false, + kind: 'codex', + location: 'local', + hostId: null, + hostName: null, + }, + ], + }, + { limit: 50, remotes, host: 'macbook' }, + ); + expect(filtered.host).toBe('macbook'); + expect(filtered.threads.every((t) => t.hostId === 'host-macbook')).toBe(true); + + const localOnly = finalizeThreadList( + { + backend: 'app-server', + limit: 50, + threads: [ + { + threadId: 'local:local-thread-1', + title: 'Local only', + pinned: false, + selected: false, + kind: 'codex', + location: 'local', + hostId: null, + hostName: null, + }, + ], + }, + { limit: 50, remotes, host: 'local' }, + ); + expect(localOnly.threads).toHaveLength(1); + expect(localOnly.threads[0]?.location).toBe('local'); + + const lookup = findRemoteThread('aaaa1111-1111-1111-1111-111111111111', env); + expect(lookup).toMatchObject({ hostId: 'host-macbook', hostName: "Zack's MacBook" }); + const err = new RemoteThreadNotLoadedError( + 'aaaa1111-1111-1111-1111-111111111111', + lookup?.hostId ?? null, + lookup?.hostName ?? null, + ); expect(err.code).toBe('REMOTE_THREAD_NOT_LOADED'); - expect(err.hostId).toBe('host-abc'); - expect(err.message).toMatch(/host-abc/); + expect(err.hostId).toBe('host-macbook'); + expect(err.hostName).toBe("Zack's MacBook"); + expect(err.hint).toMatch(/host-macbook/); + expect(err.message).toMatch(/app-server/); + }); + + it('skips malformed global-state files without throwing', async () => { + const { mkdtempSync, writeFileSync } = await import('node:fs'); + const { tmpdir } = await import('node:os'); + const { join } = await import('node:path'); + const { listRemoteThreadsFromState } = await import('../../src/core/chatgpt-desktop/index.js'); + const home = mkdtempSync(join(tmpdir(), 'gbot-remote-bad-')); + writeFileSync(join(home, '.codex-global-state.json'), '{not-json'); + expect(listRemoteThreadsFromState({ CODEX_HOME: home })).toEqual([]); + writeFileSync(join(home, '.codex-global-state.json'), JSON.stringify(['array'])); + expect(listRemoteThreadsFromState({ CODEX_HOME: home })).toEqual([]); }); }); From 241a08be0e144af6fbcd46e8d3afb4a8e382d5aa Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 01:31:24 +0000 Subject: [PATCH 11/26] feat: separate host and modelProvider list filters; add list_hosts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep host (all|local|id/name) and modelProvider→modelProviders as independent list/search filters. Add chatgpt_desktop_list_hosts / gbot chatgpt-desktop hosts with thread counts, friendly names, and modelProviders discovered via app-server list method or distinct thread/list values (hostsSource / modelProvidersSource reported). Co-authored-by: Zack Jackson --- .changeset/chatgpt-desktop-cdp.md | 2 +- docs/chatgpt-desktop-cdp.md | 52 +++-- src/cli/chatgpt-desktop/hosts.tsx | 60 ++++++ src/cli/chatgpt-desktop/search.tsx | 14 +- src/cli/chatgpt-desktop/threads.tsx | 17 +- src/core/chatgpt-desktop/adapter.ts | 11 ++ .../chatgpt-desktop/app-server-fallback.ts | 186 +++++++++++++++++- src/core/chatgpt-desktop/facade.ts | 160 +++++++++++++-- src/core/chatgpt-desktop/index.ts | 4 + src/core/chatgpt-desktop/remote-threads.ts | 71 +++++++ src/core/chatgpt-desktop/routes.ts | 38 +++- src/core/chatgpt-desktop/types.ts | 19 +- src/core/codex-bridge.js | 20 +- .../tools/chatgpt_desktop_list_hosts.tsx | 37 ++++ .../tools/chatgpt_desktop_list_threads.tsx | 10 +- .../tools/chatgpt_desktop_search_threads.tsx | 10 +- tests/route-unit/chatgpt-desktop.test.ts | 145 +++++++++++++- 17 files changed, 808 insertions(+), 48 deletions(-) create mode 100644 src/cli/chatgpt-desktop/hosts.tsx create mode 100644 src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx diff --git a/.changeset/chatgpt-desktop-cdp.md b/.changeset/chatgpt-desktop-cdp.md index ace22d3..4b03937 100644 --- a/.changeset/chatgpt-desktop-cdp.md +++ b/.changeset/chatgpt-desktop-cdp.md @@ -2,4 +2,4 @@ "grok-bot-cli": minor --- -Scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools (`chatgpt_desktop_*`). List/search merge local app-server threads with remote-control summaries from `.codex-global-state.json` (`location`/`hostId`/`host`/`groupBy`). Read returns a typed remote-thread error with host hint. Fixes `modelProviders: []` on list-threads. Reports `backend`. +Scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools (`chatgpt_desktop_*`). List/search keep separate `host` (`all`|`local`|id/name) and `modelProvider`→`modelProviders` filters. `chatgpt_desktop_list_hosts` / `gbot chatgpt-desktop hosts` discovers hosts from `remote-thread-summaries-v3` (+ optional app-server remote-env method) and modelProviders via app-server list method or distinct `thread/list`. Reports `hostsSource` / `modelProvidersSource`. Remote read returns typed error with host hint. Fixes `modelProviders: []` on list-threads. Reports `backend`. diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index 2aba9dc..1786e75 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -31,8 +31,11 @@ Override the port with `CHATGPT_DESKTOP_CDP_PORT` or `--port`. ```sh gbot chatgpt-desktop status +gbot chatgpt-desktop hosts gbot chatgpt-desktop threads --limit 20 -gbot chatgpt-desktop search "launch" +gbot chatgpt-desktop threads --host local +gbot chatgpt-desktop threads --host macbook --model-provider openai +gbot chatgpt-desktop search "launch" --host all gbot chatgpt-desktop read gbot chatgpt-desktop send --thread-id "hello" gbot chatgpt-desktop send "start a new chat with this text" @@ -43,7 +46,8 @@ gbot chatgpt-desktop send "start a new chat with this text" | Tool | Role | | --- | --- | | `chatgpt_desktop_status` | CDP `/json/version` (+ optional attach) and app-server probe | -| `chatgpt_desktop_list_threads` | App-server `thread/list` (`modelProviders: []`); merge CDP UI fields | +| `chatgpt_desktop_list_hosts` | Discover hosts + modelProviders (no hardcoding) | +| `chatgpt_desktop_list_threads` | App-server `thread/list`; merge CDP UI + remotes | | `chatgpt_desktop_search_threads` | App-server list + metadata filter | | `chatgpt_desktop_read_thread` | App-server `thread/read` + `thread/turns/list` (`itemsView: "full"`) | | `chatgpt_desktop_send` | Composer submit over CDP (new-thread-in-project included) | @@ -88,26 +92,48 @@ Surfaced list fields: `id`, `name`, `preview`, `cwd`, `createdAt` / `projectId`, `status`, `modelProvider`, `model`, `originator`. `archived` is a list filter, not a field. -`chatgpt_desktop_list_threads` merges local app-server threads with -remote-control summaries from `~/.codex/.codex-global-state.json` keys -`remote-thread-summaries-v3:` (title, ids, remote project info; pinned -ids live there too). Every row gets `location: "local" | "remote"` plus -`hostId` / `hostName` when known. Filter with `host` (hostId or friendly name; -`host: "local"` for local-only) and optionally `groupBy: "host"`. +### Host and modelProvider filters (separate) + +`chatgpt_desktop_list_threads` / search take two independent filters: + +| Filter | Values | Default | Effect | +| --- | --- | --- | --- | +| `host` | `all` \| `local` \| `` | `all` | Machine/location from remote summaries + local | +| `modelProvider` | provider id string | omit / `[]` = all | Passed through to app-server `modelProviders` | + +Optional `groupBy: "host"` returns `groups[]` keyed by host. + +### Host discovery (`chatgpt_desktop_list_hosts`) + +Hosts are discovered dynamically — do not hardcode them: + +1. Always include `local` +2. Every `remote-thread-summaries-v3:` key in + `~/.codex/.codex-global-state.json`, with friendly names and thread counts +3. If app-server exposes a remote-environment list method, merge those hosts + too (`hostsSource` names what was used) + +`modelProviders` on the same result: prefer a dedicated app-server list method +when present; otherwise distinct `modelProvider` values from `thread/list` +(`modelProviders: []`). `modelProvidersSource` names the path used. ### Remote-control threads -Remote rows appear in list/search results. `chatgpt_desktop_read_thread` on a -remote-only thread raises `RemoteThreadNotLoadedError` (`REMOTE_THREAD_NOT_LOADED`) -with `hostId`, optional `hostName`, and a `hint` to read it via that host's -app-server. SSH remoting is **not** implemented in this PR (follow-up). The -global-state parser is defensive — unknown shapes are skipped. +`chatgpt_desktop_list_threads` merges local app-server threads with +remote-control summaries (`location: "local" | "remote"` plus `hostId` / +`hostName`). Remote rows appear in list/search. `chatgpt_desktop_read_thread` +on a remote-only thread raises `RemoteThreadNotLoadedError` +(`REMOTE_THREAD_NOT_LOADED`) with `hostId`, optional `hostName`, and a `hint` +to read it via that host's app-server. SSH remoting is **not** implemented in +this PR (follow-up). The global-state parser is defensive — unknown shapes are +skipped. ## Backend capability matrix | Operation | CDP | App-server | | --- | --- | --- | | `status` | `/json/version` + attach | daemon probe | +| `list_hosts` | — | global-state keys (+ optional remote-env method) + provider discovery | | `list_threads` | merge selected / UI overlay | primary inventory + remote summaries | | `search_threads` | merge selected when connected | primary (list + filter, includes remotes) | | `read_thread` | DOM harvest / wheel **fallback only** (local) | primary; remote → typed error + host hint | diff --git a/src/cli/chatgpt-desktop/hosts.tsx b/src/cli/chatgpt-desktop/hosts.tsx new file mode 100644 index 0000000..d9afd93 --- /dev/null +++ b/src/cli/chatgpt-desktop/hosts.tsx @@ -0,0 +1,60 @@ +import { Agent } from '@agent-bundle/runtime'; +import type { CliRouteConfig, CliRouteProps } from 'agent-bundle'; +import { z } from 'zod'; + +import { + listHostsOperation, + resultSchema, + resultText, +} from '../../core/chatgpt-desktop/routes.js'; + +export const config = { + description: + 'List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.', + exitCode: 'result', + inputJsonSchema: { + additionalProperties: false, + properties: { + port: { description: 'Local CDP port', type: 'number' }, + }, + type: 'object', + }, +} satisfies CliRouteConfig; + +export const inputSchema = z + .object({ + port: z.number().int().min(1).max(65535).optional(), + }) + .strict(); +export { resultSchema }; + +export default async function chatgptDesktopHosts({ + input, +}: CliRouteProps) { + const out = await listHostsOperation(input); + const hosts = Array.isArray(out.hosts) ? out.hosts : []; + const text = + hosts.length > 0 + ? hosts + .map((host) => { + const row = host as { + hostId?: string; + hostName?: string | null; + location?: string; + threadCount?: number; + }; + const name = + row.hostName && row.hostName !== row.hostId ? ` (${row.hostName})` : ''; + return `${row.hostId ?? '?'}${name} [${row.location ?? '?'}] threads=${row.threadCount ?? 0}`; + }) + .join('\n') + + `\n\nhostsSource: ${String(out.hostsSource ?? '')}` + + `\nmodelProviders: ${JSON.stringify(out.modelProviders ?? [])}` + + `\nmodelProvidersSource: ${String(out.modelProvidersSource ?? '')}` + : resultText(out); + return ( + + {text} + + ); +} diff --git a/src/cli/chatgpt-desktop/search.tsx b/src/cli/chatgpt-desktop/search.tsx index 100ac5d..ebb8545 100644 --- a/src/cli/chatgpt-desktop/search.tsx +++ b/src/cli/chatgpt-desktop/search.tsx @@ -10,13 +10,22 @@ import { export const config = { description: - 'Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.', + 'Search ChatGPT Desktop threads; --host and --model-provider are separate filters.', exitCode: 'result', positionals: ['query'], inputJsonSchema: { additionalProperties: false, properties: { + groupBy: { description: 'Group results by host', enum: ['host'], type: 'string' }, + host: { + description: 'Filter: all (default) | local | hostId or friendly name', + type: 'string', + }, limit: { default: 50, description: 'Max matches (1-200)', type: 'number' }, + modelProvider: { + description: 'Pass-through to app-server modelProviders (omit = all)', + type: 'string', + }, port: { description: 'Local CDP port', type: 'number' }, query: { type: 'string' }, }, @@ -27,7 +36,10 @@ export const config = { export const inputSchema = z .object({ + groupBy: z.literal('host').optional(), + host: z.string().min(1).max(256).optional(), limit: z.number().int().min(1).max(200).default(50), + modelProvider: z.string().min(1).max(256).optional(), port: z.number().int().min(1).max(65535).optional(), query: z.string().min(1).max(512), }) diff --git a/src/cli/chatgpt-desktop/threads.tsx b/src/cli/chatgpt-desktop/threads.tsx index 8922b73..6fc3d5e 100644 --- a/src/cli/chatgpt-desktop/threads.tsx +++ b/src/cli/chatgpt-desktop/threads.tsx @@ -10,14 +10,21 @@ import { export const config = { description: - 'List local + remote-control ChatGPT Desktop threads; optional --host and --group-by host.', + 'List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, properties: { groupBy: { description: 'Group results by host', enum: ['host'], type: 'string' }, - host: { description: 'Filter by hostId or friendly name (local for local-only)', type: 'string' }, + host: { + description: 'Filter: all (default) | local | hostId or friendly name', + type: 'string', + }, limit: { default: 50, description: 'Max threads (1-200)', type: 'number' }, + modelProvider: { + description: 'Pass-through to app-server modelProviders (omit = all)', + type: 'string', + }, port: { description: 'Local CDP port', type: 'number' }, }, type: 'object', @@ -29,6 +36,7 @@ export const inputSchema = z groupBy: z.literal('host').optional(), host: z.string().min(1).max(256).optional(), limit: z.number().int().min(1).max(200).default(50), + modelProvider: z.string().min(1).max(256).optional(), port: z.number().int().min(1).max(65535).optional(), }) .strict(); @@ -51,15 +59,18 @@ export default async function chatgptDesktopThreads({ location?: string; hostId?: string | null; hostName?: string | null; + modelProvider?: string | null; }; const where = row.location === 'remote' ? ` [remote ${row.hostName || row.hostId || '?'}]` : ' [local]'; + const provider = row.modelProvider ? ` {${row.modelProvider}}` : ''; return ( `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : '') + - where + where + + provider ); }) .join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` diff --git a/src/core/chatgpt-desktop/adapter.ts b/src/core/chatgpt-desktop/adapter.ts index e0bffcd..9d4d89e 100644 --- a/src/core/chatgpt-desktop/adapter.ts +++ b/src/core/chatgpt-desktop/adapter.ts @@ -1,6 +1,7 @@ import type { ChatGptDesktopStatus, ChatGptDesktopTarget, + ListHostsResult, ListThreadsResult, OpenThreadResult, ReadThreadResult, @@ -17,7 +18,10 @@ export interface ChatGptDesktopAdapter { listTargets(): Promise; listThreads(options?: { limit?: number; + /** `all` (default) | `local` | hostId / friendly name. */ host?: string; + /** Passed through to app-server `modelProviders` (omit/empty = all). */ + modelProvider?: string; groupBy?: 'host'; }): Promise; /** Optional; facades that support app-server search implement this. */ @@ -25,8 +29,15 @@ export interface ChatGptDesktopAdapter { query: string; limit?: number; host?: string; + modelProvider?: string; groupBy?: 'host'; }): Promise; + /** + * Optional; facades that discover remote-control hosts implement this. + * Returns `local` + every `remote-thread-summaries-v3:` host with + * counts / friendly names, plus discovered `modelProviders`. + */ + listHosts?(): Promise; readThread(options: { threadId: string; limit?: number; diff --git a/src/core/chatgpt-desktop/app-server-fallback.ts b/src/core/chatgpt-desktop/app-server-fallback.ts index 78df82a..c5ffdd2 100644 --- a/src/core/chatgpt-desktop/app-server-fallback.ts +++ b/src/core/chatgpt-desktop/app-server-fallback.ts @@ -33,35 +33,39 @@ import type { export async function appServerListThreads({ limit = 50, cursor, + modelProviders = [], }: { limit?: number; cursor?: string; + modelProviders?: string[]; } = {}): Promise { - const out = await listCodexThreads({ limit, cursor }); + const out = await listCodexThreads({ limit, cursor, modelProviders }); return { backend: 'app-server', limit: out.limit, nextCursor: out.nextCursor ?? null, threads: out.threads.map(mapListedThread), + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, }; } export async function appServerSearchThreads({ query, limit = 50, + modelProviders = [], }: { query: string; limit?: number; + modelProviders?: string[]; }): Promise { const needle = query.trim().toLowerCase(); if (!needle) { - return appServerListThreads({ limit }); + return appServerListThreads({ limit, modelProviders }); } const matched: ChatGptDesktopThread[] = []; let cursor: string | undefined; - // Page the full inventory (modelProviders: [] is applied inside listCodexThreads). for (let page = 0; page < 20 && matched.length < limit; page++) { - const out = await listCodexThreads({ limit: 200, cursor }); + const out = await listCodexThreads({ limit: 200, cursor, modelProviders }); for (const thread of out.threads) { const mapped = mapListedThread(thread); if (threadMatchesQuery(mapped, needle)) matched.push(mapped); @@ -76,9 +80,183 @@ export async function appServerSearchThreads({ query, nextCursor: null, threads: matched.slice(0, limit), + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, }; } +/** Candidate app-server RPCs that might list configured model providers. */ +const MODEL_PROVIDER_LIST_METHODS = [ + 'modelProvider/list', + 'model/providers/list', + 'models/providers/list', + 'account/modelProviders/list', + 'config/modelProviders/list', + 'provider/list', +] as const; + +/** Candidate app-server RPCs that might list remote-control environments/hosts. */ +const REMOTE_ENVIRONMENT_LIST_METHODS = [ + 'remoteEnvironment/list', + 'remote/environments/list', + 'environment/list', + 'remoteControl/hosts/list', + 'remote/hosts/list', + 'hosts/list', +] as const; + +export type ModelProvidersDiscovery = { + readonly providers: readonly string[]; + /** Which discovery path produced the list. */ + readonly source: + | `app-server:${(typeof MODEL_PROVIDER_LIST_METHODS)[number]}` + | 'thread/list-distinct'; +}; + +export type RemoteEnvironmentsDiscovery = { + readonly hosts: readonly { hostId: string; hostName: string | null }[]; + readonly source: `app-server:${(typeof REMOTE_ENVIRONMENT_LIST_METHODS)[number]}` | null; +}; + +/** + * Discover configured model providers. Prefers a dedicated app-server list + * method when present; otherwise distinct `modelProvider` values from + * `thread/list` (`modelProviders: []`). + */ +export async function discoverModelProviders(): Promise { + const { client } = await openCodexSession(); + try { + for (const method of MODEL_PROVIDER_LIST_METHODS) { + try { + const result = await client.request(method, {}) as unknown; + const providers = normalizeNamedList(result, [ + 'id', + 'name', + 'provider', + 'modelProvider', + 'slug', + ]); + if (providers.length > 0) { + return { providers, source: `app-server:${method}` }; + } + } catch { + // Method missing or rejected — try the next candidate. + } + } + } finally { + client.close(); + } + + const providers = new Set(); + let cursor: string | undefined; + for (let page = 0; page < 20; page++) { + const out = await listCodexThreads({ limit: 200, cursor, modelProviders: [] }); + for (const thread of out.threads) { + if (typeof thread.modelProvider === 'string' && thread.modelProvider) { + providers.add(thread.modelProvider); + } + } + if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + cursor = out.nextCursor; + } + return { + providers: [...providers].sort(), + source: 'thread/list-distinct', + }; +} + +/** + * Probe app-server for a remote-environment / hosts list method. + * Returns null source when no such method exists (callers fall back to + * `remote-thread-summaries-v3:` keys in global state). + */ +export async function discoverRemoteEnvironments(): Promise { + const { client } = await openCodexSession(); + try { + for (const method of REMOTE_ENVIRONMENT_LIST_METHODS) { + try { + const result = await client.request(method, {}) as unknown; + const hosts = normalizeHostEntries(result); + if (hosts.length > 0) { + return { hosts, source: `app-server:${method}` }; + } + } catch { + // Method missing or rejected — try the next candidate. + } + } + } finally { + client.close(); + } + return { hosts: [], source: null }; +} + +function normalizeNamedList(result: unknown, idKeys: string[]): string[] { + const raw = listPayload(result); + const out: string[] = []; + for (const entry of raw) { + if (typeof entry === 'string' && entry) out.push(entry); + else if (entry && typeof entry === 'object') { + const row = entry as Record; + for (const key of idKeys) { + if (typeof row[key] === 'string' && row[key]) { + out.push(String(row[key])); + break; + } + } + } + } + return [...new Set(out)].sort(); +} + +function normalizeHostEntries( + result: unknown, +): { hostId: string; hostName: string | null }[] { + const raw = listPayload(result); + const out: { hostId: string; hostName: string | null }[] = []; + for (const entry of raw) { + if (typeof entry === 'string' && entry) { + out.push({ hostId: entry, hostName: null }); + continue; + } + if (!entry || typeof entry !== 'object') continue; + const row = entry as Record; + let hostId: string | null = null; + for (const key of ['hostId', 'id', 'uuid', 'environmentId', 'envId']) { + if (typeof row[key] === 'string' && row[key]) { + hostId = String(row[key]); + break; + } + } + if (!hostId) continue; + let hostName: string | null = null; + for (const key of ['hostName', 'name', 'displayName', 'envName', 'label', 'title']) { + if (typeof row[key] === 'string' && row[key]) { + hostName = String(row[key]); + break; + } + } + out.push({ hostId, hostName }); + } + return out; +} + +function listPayload(result: unknown): unknown[] { + if (Array.isArray(result)) return result; + if (!result || typeof result !== 'object') return []; + const record = result as Record; + for (const key of [ + 'data', + 'providers', + 'modelProviders', + 'hosts', + 'environments', + 'remoteEnvironments', + 'items', + ]) { + if (Array.isArray(record[key])) return record[key] as unknown[]; + } + return []; +} + export async function appServerReadThread({ threadId, limit = 100, diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index 899735a..1d990ae 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -5,10 +5,12 @@ import { appServerReadThread, appServerSearchThreads, appServerStatusProbe, + discoverModelProviders, + discoverRemoteEnvironments, } from './app-server-fallback.js'; import { CdpUnreachableError, NotImplementedError, RemoteThreadNotLoadedError } from './errors.js'; import { resolveCdpPort } from './loopback.js'; -import { listRemoteThreadsFromState } from './remote-threads.js'; +import { listDiscoveredHosts, listRemoteThreadsFromState } from './remote-threads.js'; import { isTemporaryDesktopThreadId, threadIdsEquivalent, @@ -19,6 +21,7 @@ import type { ChatGptDesktopStatus, ChatGptDesktopTarget, ChatGptDesktopThread, + ListHostsResult, ListThreadsResult, OpenThreadResult, ReadThreadResult, @@ -33,6 +36,9 @@ export type ChatGptDesktopFallbacks = { readThread: typeof appServerReadThread; statusProbe: typeof appServerStatusProbe; listRemoteThreads?: typeof listRemoteThreadsFromState; + listHosts?: typeof listDiscoveredHosts; + discoverModelProviders?: typeof discoverModelProviders; + discoverRemoteEnvironments?: typeof discoverRemoteEnvironments; }; const defaultFallbacks: ChatGptDesktopFallbacks = { @@ -41,12 +47,23 @@ const defaultFallbacks: ChatGptDesktopFallbacks = { readThread: appServerReadThread, statusProbe: appServerStatusProbe, listRemoteThreads: listRemoteThreadsFromState, + listHosts: listDiscoveredHosts, + discoverModelProviders, + discoverRemoteEnvironments, }; export type ListThreadsOptions = { limit?: number; - /** Filter by remote hostId or friendly host/env name (substring, case-insensitive). */ + /** + * Machine / location filter discovered from remote summaries + `local`. + * `all` (default) | `local` | ``. + */ host?: string; + /** + * Passed through to app-server `thread/list` as `modelProviders`. + * Omit / empty = all providers (`modelProviders: []`). + */ + modelProvider?: string; /** When `"host"`, also return `groups` keyed by host. */ groupBy?: 'host'; }; @@ -93,10 +110,12 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { async listThreads(options: ListThreadsOptions = {}): Promise { const limit = options.limit ?? 50; + const host = normalizeHostFilter(options.host); + const modelProviders = modelProvidersFromFilter(options.modelProvider); let appList: ListThreadsResult | null = null; let appError: unknown; try { - appList = await this.#fallbacks.listThreads({ limit }); + appList = await this.#fallbacks.listThreads({ limit, modelProviders }); } catch (error) { appError = error; } @@ -124,29 +143,117 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { return finalizeThreadList(base, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: this.#listRemotes(), }); } + async listHosts(): Promise { + const remotes = this.#listRemotes(); + let localThreadCount = 0; + try { + const local = await this.#fallbacks.listThreads({ limit: 200, modelProviders: [] }); + localThreadCount = local.threads.length; + } catch { + localThreadCount = 0; + } + const listHosts = this.#fallbacks.listHosts ?? listDiscoveredHosts; + const fromState = listHosts(process.env, { localThreadCount }); + const byId = new Map(fromState.map((host) => [host.hostId, { ...host }])); + + let hostsSource = 'remote-thread-summaries-v3+local'; + try { + const discoverEnvs = + this.#fallbacks.discoverRemoteEnvironments ?? discoverRemoteEnvironments; + const appHosts = await discoverEnvs(); + if (appHosts.source && appHosts.hosts.length > 0) { + for (const host of appHosts.hosts) { + const existing = byId.get(host.hostId); + if (existing) { + byId.set(host.hostId, { + ...existing, + hostName: existing.hostName ?? host.hostName, + }); + } else { + byId.set(host.hostId, { + hostId: host.hostId, + hostName: host.hostName, + location: 'remote', + threadCount: 0, + }); + } + } + hostsSource = `${appHosts.source}+remote-thread-summaries-v3+local`; + } + } catch { + // App-server remote-env probe unavailable — keep global-state hosts. + } + + // Recount remotes from the parsed summary rows for accuracy. + const remoteCounts = new Map(); + for (const thread of remotes) { + remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + } + const withCounts = [...byId.values()] + .map((host) => + host.hostId === 'local' + ? { ...host, threadCount: localThreadCount } + : { ...host, threadCount: remoteCounts.get(host.hostId) ?? host.threadCount }, + ) + .sort((a, b) => { + if (a.hostId === 'local') return -1; + if (b.hostId === 'local') return 1; + return a.hostId.localeCompare(b.hostId); + }); + + let modelProviders: string[] = []; + let modelProvidersSource = 'thread/list-distinct'; + try { + const discover = this.#fallbacks.discoverModelProviders ?? discoverModelProviders; + const discovered = await discover(); + modelProviders = [...discovered.providers]; + modelProvidersSource = discovered.source; + } catch { + modelProviders = [...new Set( + remotes + .map((thread) => thread.modelProvider) + .filter((value): value is string => typeof value === 'string' && Boolean(value)), + )].sort(); + modelProvidersSource = 'remote-summaries-distinct'; + } + return { + hosts: withCounts, + hostsSource, + modelProviders, + modelProvidersSource, + backend: 'app-server', + }; + } + async searchThreads(options: { query: string; limit?: number; host?: string; + modelProvider?: string; groupBy?: 'host'; }): Promise { const limit = options.limit ?? 50; + const host = normalizeHostFilter(options.host); + const modelProviders = modelProvidersFromFilter(options.modelProvider); try { const appList = await this.#fallbacks.searchThreads({ query: options.query, limit, + modelProviders, }); const cdpList = await this.#tryCdpList({ limit }); const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; const withRemotes = finalizeThreadList(base, { limit: 10_000, - host: options.host, + host, + modelProvider: options.modelProvider, remotes: this.#listRemotes(), }); const needle = options.query.trim().toLowerCase(); @@ -157,7 +264,8 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { }; return finalizeThreadList(filtered, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: [], }); @@ -172,7 +280,8 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { }; return finalizeThreadList(filtered, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: this.#listRemotes(), }); @@ -356,12 +465,14 @@ export function finalizeThreadList( base: ListThreadsResult, { limit, - host, + host = 'all', + modelProvider, groupBy, remotes, }: { limit: number; host?: string; + modelProvider?: string; groupBy?: 'host'; remotes: readonly ChatGptDesktopThread[]; }, @@ -391,9 +502,11 @@ export function finalizeThreadList( }); } - const filtered = host - ? merged.filter((thread) => hostMatches(thread, host)) - : merged; + const filtered = merged.filter((thread) => { + if (!hostMatches(thread, host)) return false; + if (!modelProviderMatches(thread, modelProvider)) return false; + return true; + }); const limited = filtered.slice(0, limit); const result: ListThreadsResult = { backend: base.backend, @@ -401,7 +514,8 @@ export function finalizeThreadList( threads: limited, ...(base.nextCursor !== undefined ? { nextCursor: base.nextCursor } : {}), ...(base.query !== undefined ? { query: base.query } : {}), - ...(host ? { host } : {}), + host, + ...(modelProvider ? { modelProvider } : {}), }; if (groupBy === 'host') { return { ...result, groupBy: 'host', groups: groupThreadsByHost(limited) }; @@ -432,14 +546,34 @@ export function groupThreadsByHost( return [...groups.values()]; } +function normalizeHostFilter(host?: string): string { + const value = (host ?? 'all').trim(); + return value || 'all'; +} + +function modelProvidersFromFilter(modelProvider?: string): string[] { + if (!modelProvider || !modelProvider.trim()) return []; + return [modelProvider.trim()]; +} + function hostMatches(thread: ChatGptDesktopThread, host: string): boolean { const needle = host.trim().toLowerCase(); - if (!needle) return true; + if (!needle || needle === 'all') return true; if (needle === 'local') return (thread.location ?? 'local') === 'local'; return [thread.hostId, thread.hostName] .some((value) => typeof value === 'string' && value.toLowerCase().includes(needle)); } +function modelProviderMatches(thread: ChatGptDesktopThread, modelProvider?: string): boolean { + if (!modelProvider) return true; + if (!thread.modelProvider) { + // Remote summaries often omit provider — keep them; local rows from a + // filtered thread/list already match the server-side modelProviders filter. + return thread.location === 'remote'; + } + return thread.modelProvider === modelProvider; +} + function threadMatchesQuery(thread: ChatGptDesktopThread, needle: string): boolean { if (!needle) return true; return [thread.title, thread.threadId, thread.project, thread.preview, thread.hostName, thread.hostId] diff --git a/src/core/chatgpt-desktop/index.ts b/src/core/chatgpt-desktop/index.ts index be78682..9ec1756 100644 --- a/src/core/chatgpt-desktop/index.ts +++ b/src/core/chatgpt-desktop/index.ts @@ -49,6 +49,7 @@ export { codexGlobalStatePath, findRemoteThread, findRemoteThreadHostId, + listDiscoveredHosts, listRemoteThreadsFromState, loadCodexGlobalState, } from './remote-threads.js'; @@ -69,6 +70,8 @@ export { relaunchChatGptDesktopWithCdp, } from './relaunch.js'; export { + listHostsOperation, + listHostsSchema, listThreadsOperation, listThreadsSchema, readThreadOperation, @@ -93,6 +96,7 @@ export type { ChatGptDesktopThreadLocation, ChatGptDesktopThreadSection, ChatGptDesktopTurn, + ListHostsResult, ListThreadsResult, OpenThreadResult, ReadThreadResult, diff --git a/src/core/chatgpt-desktop/remote-threads.ts b/src/core/chatgpt-desktop/remote-threads.ts index 2976296..6bdfb45 100644 --- a/src/core/chatgpt-desktop/remote-threads.ts +++ b/src/core/chatgpt-desktop/remote-threads.ts @@ -115,6 +115,77 @@ export function findRemoteThreadHostId( return findRemoteThread(threadId, env)?.hostId ?? null; } +export type DiscoveredHost = { + readonly hostId: string; + readonly hostName: string | null; + readonly location: 'local' | 'remote'; + readonly threadCount: number; +}; + +/** + * Discover hosts dynamically: always include `local`, plus every + * `remote-thread-summaries-v3:` key (with friendly names / counts). + */ +export function listDiscoveredHosts( + env: NodeJS.ProcessEnv = process.env, + { + localThreadCount = 0, + }: { + localThreadCount?: number; + } = {}, +): DiscoveredHost[] { + const remotes = listRemoteThreadsFromState(env); + const byHost = new Map(); + byHost.set('local', { + hostId: 'local', + hostName: 'local', + location: 'local', + threadCount: localThreadCount, + }); + + const data = loadCodexGlobalState(env); + if (data) { + const hostNames = collectHostNames(data); + for (const key of Object.keys(data)) { + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match?.[1]) continue; + const hostId = match[1]; + const summary = data[key]; + const hostName = hostNames.get(hostId) ?? extractHostName(summary) ?? null; + byHost.set(hostId, { + hostId, + hostName, + location: 'remote', + threadCount: 0, + }); + } + } + + for (const thread of remotes) { + const existing = byHost.get(thread.hostId); + if (existing) { + byHost.set(thread.hostId, { + ...existing, + hostName: existing.hostName ?? thread.hostName, + threadCount: existing.threadCount + 1, + }); + } else { + byHost.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName, + location: 'remote', + threadCount: 1, + }); + } + } + + return [...byHost.values()].sort((a, b) => { + if (a.hostId === 'local') return -1; + if (b.hostId === 'local') return 1; + return a.hostId.localeCompare(b.hostId); + }); +} + function collectHostNames(data: Record): Map { const names = new Map(); for (const [key, value] of Object.entries(data)) { diff --git a/src/core/chatgpt-desktop/routes.ts b/src/core/chatgpt-desktop/routes.ts index f1a0888..2c5b349 100644 --- a/src/core/chatgpt-desktop/routes.ts +++ b/src/core/chatgpt-desktop/routes.ts @@ -17,7 +17,10 @@ export const listThreadsSchema = z .object({ port: z.number().int().min(1).max(65535).optional(), limit: z.number().int().min(1).max(200).default(50), + /** `all` (default) | `local` | hostId / friendly name. */ host: z.string().min(1).max(256).optional(), + /** Passed through to app-server `modelProviders` (omit = all). */ + modelProvider: z.string().min(1).max(256).optional(), groupBy: z.literal('host').optional(), }) .strict(); @@ -28,10 +31,17 @@ export const searchThreadsSchema = z query: z.string().min(1).max(512), limit: z.number().int().min(1).max(200).default(50), host: z.string().min(1).max(256).optional(), + modelProvider: z.string().min(1).max(256).optional(), groupBy: z.literal('host').optional(), }) .strict(); +export const listHostsSchema = z + .object({ + port: z.number().int().min(1).max(65535).optional(), + }) + .strict(); + export const readThreadSchema = z .object({ port: z.number().int().min(1).max(65535).optional(), @@ -136,6 +146,7 @@ export async function listThreadsOperation( adapter.listThreads({ limit: input.limit, host: input.host, + modelProvider: input.modelProvider, groupBy: input.groupBy, }), ); @@ -157,6 +168,7 @@ export async function searchThreadsOperation( query: input.query, limit: input.limit, host: input.host, + modelProvider: input.modelProvider, groupBy: input.groupBy, }); }); @@ -166,6 +178,22 @@ export async function searchThreadsOperation( } } +export async function listHostsOperation( + input: z.infer, +): Promise { + try { + const out = await withAdapter(input.port, async (adapter) => { + if (typeof adapter.listHosts !== 'function') { + throw new NotImplementedError('listHosts', 'adapter does not implement listHosts'); + } + return adapter.listHosts(); + }); + return asResult({ ...out, exitCode: 0 as const }); + } catch (error) { + return mapError(error); + } +} + export async function readThreadOperation( input: z.infer, ): Promise { @@ -228,9 +256,17 @@ export function resultText(result: OperationResult): string { return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); + if (Array.isArray(result.hosts)) { + const providers = Array.isArray(result.modelProviders) + ? ` providers=${result.modelProviders.length} (${String(result.modelProvidersSource ?? '')})` + : ''; + return `${result.hosts.length} hosts via ${String(result.hostsSource ?? result.backend ?? 'unknown')}${providers}`; + } if (Array.isArray(result.threads)) { const via = result.query ? ` matching ${JSON.stringify(result.query)}` : ''; - return `${result.threads.length} threads${via} via ${result.backend ?? 'unknown'}`; + const host = result.host && result.host !== 'all' ? ` host=${result.host}` : ''; + const provider = result.modelProvider ? ` provider=${result.modelProvider}` : ''; + return `${result.threads.length} threads${via}${host}${provider} via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { const mode = result.full ? 'full' : 'page'; diff --git a/src/core/chatgpt-desktop/types.ts b/src/core/chatgpt-desktop/types.ts index b8a1f2b..644594b 100644 --- a/src/core/chatgpt-desktop/types.ts +++ b/src/core/chatgpt-desktop/types.ts @@ -86,13 +86,30 @@ export type ListThreadsResult = { readonly limit: number; readonly nextCursor?: string | null; readonly query?: string; - /** Host filter applied (`hostId` or friendly name substring). */ + /** Host filter applied: `all` | `local` | hostId / friendly name. */ readonly host?: string; + /** Model-provider filter passed through to app-server `modelProviders`. */ + readonly modelProvider?: string; readonly groupBy?: 'host'; /** Present when `groupBy: "host"`. */ readonly groups?: readonly ChatGptDesktopHostGroup[]; }; +export type ListHostsResult = { + readonly hosts: readonly { + readonly hostId: string; + readonly hostName: string | null; + readonly location: ChatGptDesktopThreadLocation; + readonly threadCount: number; + }[]; + /** How hosts were discovered (e.g. remote-thread-summaries-v3+local). */ + readonly hostsSource: string; + readonly modelProviders: readonly string[]; + /** How model providers were discovered (app-server method or thread/list-distinct). */ + readonly modelProvidersSource: string; + readonly backend: ChatGptDesktopBackend; +}; + export type ReadThreadResult = { readonly threadId: string; readonly turns: readonly ChatGptDesktopTurn[]; diff --git a/src/core/codex-bridge.js b/src/core/codex-bridge.js index 594d522..d7a79c9 100644 --- a/src/core/codex-bridge.js +++ b/src/core/codex-bridge.js @@ -859,22 +859,30 @@ function summarizeThread(t) { const THREAD_LIST_MAX_LIMIT = 200; /** - * @param {{ limit?: number, cursor?: string, env?: NodeJS.ProcessEnv }} [opts] + * @param {{ limit?: number, cursor?: string, modelProviders?: string[], env?: NodeJS.ProcessEnv }} [opts] */ -export async function listCodexThreads({ limit = 20, cursor, env = process.env } = {}) { +export async function listCodexThreads({ + limit = 20, + cursor, + modelProviders = [], + env = process.env, +} = {}) { if (!Number.isInteger(limit) || limit < 1 || limit > THREAD_LIST_MAX_LIMIT) { throw new RangeError("--limit must be an integer 1-" + THREAD_LIST_MAX_LIMIT); } if (cursor !== undefined && (typeof cursor !== "string" || !cursor)) throw new RangeError("--cursor must be a non-empty string"); + if (!Array.isArray(modelProviders) || modelProviders.some((p) => typeof p !== "string")) { + throw new RangeError("modelProviders must be an array of strings (empty = all providers)"); + } const { client } = await openSession(env); try { - // Default thread/list filters to the current model provider and misses other - // providers' threads. Pass modelProviders: [] for the full inventory. - // useStateDbOnly avoids a cold rollout rescan (tens of seconds). + // Default daemon filter is the current provider only. Pass modelProviders: [] for + // every provider, or a non-empty list to restrict. useStateDbOnly avoids a cold + // rollout rescan (tens of seconds). const params = { limit, useStateDbOnly: true, - modelProviders: [], + modelProviders, ...(cursor !== undefined ? { cursor } : {}), }; let out; diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx new file mode 100644 index 0000000..e313506 --- /dev/null +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx @@ -0,0 +1,37 @@ +import { Agent } from '@agent-bundle/runtime'; +import { defineTool } from 'agent-bundle/routes'; +import { + listHostsOperation, + listHostsSchema as inputSchema, + resultSchema, + resultText, +} from '../../../core/chatgpt-desktop/routes.js'; + +export { inputSchema }; + +export default defineTool( + { + title: 'ChatGPT Desktop list hosts', + description: + 'Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.', + annotations: { readOnlyHint: true }, + inputSchema, + resultSchema, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { type: 'number' }, + }, + required: [], + }, + }, + async (input) => { + const out = await listHostsOperation(input); + return ( + + {resultText(out)} + + ); + }, +); diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx index d8a2085..9b70d3f 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list threads', description: - 'List ChatGPT Desktop / Codex threads: local app-server thread/list (modelProviders:[]) merged with remote-control summaries from ~/.codex/.codex-global-state.json (remote-thread-summaries-v3:). Each thread has location local|remote and hostId/hostName. Optional host filter and groupBy=host. Merges CDP selected when connected. Result includes backend.', + 'List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -25,7 +25,13 @@ export default defineTool( limit: { type: 'number', description: 'Maximum threads (1-200).' }, host: { type: 'string', - description: 'Filter by hostId or friendly host/env name (use "local" for local-only).', + description: + 'Machine/location filter: "all" (default), "local", or a hostId / friendly name from chatgpt_desktop_list_hosts.', + }, + modelProvider: { + type: 'string', + description: + 'Filter passed through to app-server thread/list modelProviders. Omit for all providers.', }, groupBy: { type: 'string', diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx index 662a07f..3bddf19 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop search threads', description: - 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries in ~/.codex/.codex-global-state.json. Optional host filter and groupBy=host. Merges CDP selected/pinned when connected. Result includes backend.', + 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -26,7 +26,13 @@ export default defineTool( limit: { type: 'number', description: 'Maximum matches (1-200).' }, host: { type: 'string', - description: 'Filter by hostId or friendly host/env name (use "local" for local-only).', + description: + 'Machine/location filter: "all" (default), "local", or a hostId / friendly name from chatgpt_desktop_list_hosts.', + }, + modelProvider: { + type: 'string', + description: + 'Filter passed through to app-server thread/list modelProviders. Omit for all providers.', }, groupBy: { type: 'string', diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index ae4c9b5..00295ba 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -17,6 +17,7 @@ import { import { ChatGptDesktopFacade } from '../../src/core/chatgpt-desktop/facade.js'; const desktopTools = [ + 'chatgpt_desktop_list_hosts', 'chatgpt_desktop_list_threads', 'chatgpt_desktop_read_thread', 'chatgpt_desktop_search_threads', @@ -43,6 +44,7 @@ function fakeAdapter(overrides: Partial = {}): ChatGptDes return { backend: 'cdp', limit, + host: 'all', threads: [ { threadId: 'local:11111111-1111-1111-1111-111111111111', @@ -50,10 +52,30 @@ function fakeAdapter(overrides: Partial = {}): ChatGptDes pinned: false, selected: true, kind: 'local', + location: 'local', + hostId: null, + hostName: null, }, ].slice(0, limit), }; }, + async listHosts() { + return { + backend: 'app-server', + hostsSource: 'remote-thread-summaries-v3+local', + modelProviders: ['openai'], + modelProvidersSource: 'thread/list-distinct', + hosts: [ + { hostId: 'local', hostName: 'local', location: 'local', threadCount: 1 }, + { + hostId: 'host-macbook', + hostName: "Zack's MacBook", + location: 'remote', + threadCount: 2, + }, + ], + }; + }, async readThread({ threadId, limit = 100, full = false }) { return { threadId, @@ -283,6 +305,22 @@ describe('chatgpt-desktop MCP tools', () => { exitCode: 0, }); + const hosts = await invokeMcpTool('chatgpt_desktop_list_hosts', { + server: 'grok-bot', + input: {}, + }); + expect(hosts.isError).toBe(false); + expect(hosts.structuredContent).toMatchObject({ + exitCode: 0, + hostsSource: 'remote-thread-summaries-v3+local', + modelProvidersSource: 'thread/list-distinct', + modelProviders: ['openai'], + hosts: [ + { hostId: 'local', location: 'local' }, + { hostId: 'host-macbook', hostName: "Zack's MacBook" }, + ], + }); + const listed = await invokeMcpTool('chatgpt_desktop_list_threads', { server: 'grok-bot', input: { limit: 10 }, @@ -361,13 +399,20 @@ describe('chatgpt-desktop MCP tools', () => { }); describe('chatgpt-desktop CLI', () => { - it('dispatches status|threads|read|send through the fake adapter', async () => { + it('dispatches status|hosts|threads|read|send through the fake adapter', async () => { setChatGptDesktopAdapterForTests(fakeAdapter()); const status = await invokeCli(['chatgpt-desktop', 'status', '--json']); expect(status.exitCode).toBe(0); expect(status.value).toMatchObject({ reachable: true, host: '127.0.0.1' }); + const hosts = await invokeCli(['chatgpt-desktop', 'hosts', '--json']); + expect(hosts.exitCode).toBe(0); + expect(hosts.value).toMatchObject({ + hostsSource: 'remote-thread-summaries-v3+local', + modelProvidersSource: 'thread/list-distinct', + }); + const threads = await invokeCli(['chatgpt-desktop', 'threads', '--limit', '5', '--json']); expect(threads.exitCode).toBe(0); expect(threads.value).toMatchObject({ backend: 'cdp' }); @@ -858,6 +903,7 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () location: 'local', hostId: null, hostName: null, + modelProvider: 'openai', }, ], }, @@ -866,6 +912,103 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () expect(localOnly.threads).toHaveLength(1); expect(localOnly.threads[0]?.location).toBe('local'); + const byProvider = finalizeThreadList( + { + backend: 'app-server', + limit: 50, + threads: [ + { + threadId: 'local:local-thread-1', + title: 'Local only', + pinned: false, + selected: false, + kind: 'codex', + location: 'local', + hostId: null, + hostName: null, + modelProvider: 'openai', + }, + { + threadId: 'local:local-thread-2', + title: 'Other provider', + pinned: false, + selected: false, + kind: 'codex', + location: 'local', + hostId: null, + hostName: null, + modelProvider: 'anthropic', + }, + ], + }, + { limit: 50, remotes: [], host: 'all', modelProvider: 'openai' }, + ); + expect(byProvider.modelProvider).toBe('openai'); + expect(byProvider.threads).toHaveLength(1); + expect(byProvider.threads[0]?.modelProvider).toBe('openai'); + + const { + listDiscoveredHosts, + } = await import('../../src/core/chatgpt-desktop/index.js'); + const discovered = listDiscoveredHosts(env, { localThreadCount: 3 }); + expect(discovered.map((h) => h.hostId)).toEqual([ + 'local', + 'broken-host', + 'host-linux', + 'host-macbook', + ]); + expect(discovered.find((h) => h.hostId === 'local')?.threadCount).toBe(3); + expect(discovered.find((h) => h.hostId === 'host-macbook')).toMatchObject({ + hostName: "Zack's MacBook", + threadCount: 2, + location: 'remote', + }); + + const facade = new ChatGptDesktopFacade( + fakeAdapter({ + async connect() { + throw new CdpUnreachableError('offline'); + }, + async listThreads() { + throw new CdpUnreachableError('offline'); + }, + }), + 9222, + { + listThreads: async ({ limit = 50 } = {}) => ({ + backend: 'app-server' as const, + limit, + threads: [ + { + threadId: 'local:local-1', + title: 'Local', + pinned: false, + selected: false, + kind: 'codex', + modelProvider: 'openai', + }, + ], + }), + searchThreads: async () => ({ backend: 'app-server' as const, limit: 1, query: '', threads: [] }), + readThread: async () => { + throw new Error('unused'); + }, + statusProbe: async () => ({ reachable: true, mode: 'daemon' }), + listRemoteThreads: () => remotes, + discoverModelProviders: async () => ({ + providers: ['openai', 'anthropic'], + source: 'thread/list-distinct' as const, + }), + discoverRemoteEnvironments: async () => ({ hosts: [], source: null }), + }, + ); + const hostList = await facade.listHosts(); + expect(hostList.hostsSource).toBe('remote-thread-summaries-v3+local'); + expect(hostList.modelProvidersSource).toBe('thread/list-distinct'); + expect(hostList.modelProviders).toEqual(['openai', 'anthropic']); + expect(hostList.hosts.find((h) => h.hostId === 'local')?.threadCount).toBe(1); + expect(hostList.hosts.find((h) => h.hostId === 'host-macbook')?.threadCount).toBe(2); + const lookup = findRemoteThread('aaaa1111-1111-1111-1111-111111111111', env); expect(lookup).toMatchObject({ hostId: 'host-macbook', hostName: "Zack's MacBook" }); const err = new RemoteThreadNotLoadedError( From 386ca5c5d9318982c3576867bec187e025589914 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 01:32:26 +0000 Subject: [PATCH 12/26] fix: include remotes in listHosts even without global-state env When listRemoteThreads is injected (or remotes arrive without a matching CODEX_HOME), still surface those hostIds with accurate thread counts. Rebuild artifacts for chatgpt_desktop_list_hosts. Co-authored-by: Zack Jackson --- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 745 ++++++++++++---- artifact/bin/gbot.mjs | 804 ++++++++++++++---- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 659 +++++++++++--- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 646 ++++++++++++-- artifact/scripts/gbot-relay.mjs | 7 +- src/core/chatgpt-desktop/facade.ts | 19 + tests/route-unit/chatgpt-desktop.test.ts | 10 +- 9 files changed, 2410 insertions(+), 484 deletions(-) diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 57c17e4..82057bf 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"16e93721146ab76a220e53147d518b38cfe73bbd06bd3a6da0a2f135db239177"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"112cf018afc4c8a0f93d4ac36594723d6c91a8bda824e87232a8da41df6d71ef"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"01067afcfdeb3718eda40356e390714c113d55cbccdf1575168e47c12917839e"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"847a4773d30de34c142927c6c2d8d63c580e8f5d4b688631ea5751e4bf08f70f"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"cb1b5f1beee1135f846f1e1ba0caf78a4e8cba7abc29b12cdbb110cd05b44e25"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"9de6133a4be254740f94b7adc0f127d1944af08699816b4f78d4c8b7465843dd"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"2db5083337425e528943c4eec837d81ff079c787573e41fe3b4610adad63111b"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"0607539fd2c35038761f036925a92fa656e27ac45acdb23721e64882fe04d556"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"f34c137c230bcc7b07cbc039ac7ee522a35c649851051cd171b09aecb04de523"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"956ee3ba0344d53f4bdaa2fa08fc30968dd1f90ec203088c4bf76507db537a31"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 0289427..c54c826 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"8d7da26a208daba2f01936da4ff41ef1b323af6f554bc966f0c1f35e3009799e","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"e0a3032b7ad4a09b3d1e6e147f2da8e8f0d9167030dbc139055985239cb4c98b","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"406b1f82b6c7225a1cbbffb201fdc628c6bdb6aee85319a2020b49d3dedd33ad"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"9f759aa54376d5c4a15379062a36f313699416573b77a1cb427698eefab2d55d"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"f7c39813e719de53abbd4bd4dc99e3cc606253b3235ee04a9b346582bff771ce"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"42dba18d7b3223dbe5a96cd6fee98bd0f72f7977f5e6a801c6553f315ff94af7"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"f67c250a2c4782fa7de84fb11d58233c775dc75beef8730118412abe71b4209d"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"4bc901aafd21db850516dbd71fe7bbe07192b2052b7d202c88fa90c53ade2ee3"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"2b702242143aced01100bc95be40ffd41e72863496ed4e041fbc24cc68506fa9"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"8a45cab48d9f02da4fa2118e0a238696ab2f4ee198faff45ac64580c1f687d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"98edba7908cecffb141018bc358074f2785baf84bd76c4e9564843d48ad9e2dd"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"a7304f85f284dd0724475fed292a4ea17714b49061a0f6a6921d0d9899b1fa05"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"a57cb0a5ab3e7fc87331c09d4672a1266c22632594e9546aad79d907bbb63d61"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"d092282751a9572fe65b135192201070da4fb75b2517267ee090846e3d6ea57e"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"c9f96c4d20d2f8c07c603ed404517d9184712730bd1283a813454b14014f8386"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"fc81f39813276989cd0e5cd62ae93febf077380bd678f71235c82d1dc60d8c63"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"4c6785207b4216b2815068f68d438b3cbb6e480f684a661dc8f25d5e4b053e1b"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"817d0a0aa9496a3b1b7235a6cbb0b83cc1fde087a3279437925d512089d6797a"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"655891a361725bad8463a333f9650e9ff8f70512a750c73be93a56326bd62cab"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"603719e36242d374225a0de767f1014dc6dae2c0819ff9405fdb806736a93d01"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"54b5d7fdb29c98d09f3bec8d4f03efdd2abf9a8b1026aed5cb4f1b890def281a"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"7f21f53f2ba99894d65b3dee8518f9483805fc2bda9444939a5a1fa44d74df30"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"b66856473b10327fc5c661d684b773ca0e4674821130a3072f198d498f56d8e6"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"d4282ddc4619978d0a0cf76e898d9495fc058935832a42fc8a7a14c56fa1566a"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"418981b646ce72e99f803ee763fa971ba7aa4b1eff6201c2c9d8271e8109bf55"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22291,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"6fef17dd2b46fc7d05c4f47cd3b0bf981a0911eab9578405c641a0687f3cd9a4"},{"bytes":1477411,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"16e93721146ab76a220e53147d518b38cfe73bbd06bd3a6da0a2f135db239177"},{"bytes":2338537,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"112cf018afc4c8a0f93d4ac36594723d6c91a8bda824e87232a8da41df6d71ef"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1396734,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"01067afcfdeb3718eda40356e390714c113d55cbccdf1575168e47c12917839e"},{"bytes":3223043,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"847a4773d30de34c142927c6c2d8d63c580e8f5d4b688631ea5751e4bf08f70f"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1281817,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"cb1b5f1beee1135f846f1e1ba0caf78a4e8cba7abc29b12cdbb110cd05b44e25"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.","exitCode":"result","options":[{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads; optional --host and --group-by host.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter by hostId or friendly name (local for local-only)","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads; optional --host and --group-by host.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter by hostId or friendly name (local for local-only)","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter by hostId or friendly name (local for local-only)","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Filter by hostId or friendly host/env name (use \"local\" for local-only).","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Filter by hostId or friendly host/env name (use \"local\" for local-only).","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"cce12bbd861fd28d22a048dff73ca2bd24af2be91556b18e9167d8721ebfee23","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list (modelProviders:[]) merged with remote-control summaries from ~/.codex/.codex-global-state.json (remote-thread-summaries-v3:). Each thread has location local|remote and hostId/hostName. Optional host filter and groupBy=host. Merges CDP selected when connected. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Filter by hostId or friendly host/env name (use \"local\" for local-only).","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries in ~/.codex/.codex-global-state.json. Optional host filter and groupBy=host. Merges CDP selected/pinned when connected. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Filter by hostId or friendly host/env name (use \"local\" for local-only).","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"20100872aa652400dfbd7e3a2e09377c0a6c53c6d710278de9d432d58179b3b4","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"3b68c5e6e360f88e0d10ab970ca5a76e74dd6ba9a70af7b998180e5b52aba118","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"321dfc46762ffeff35c4cdbe3905bd77593804b36fa07601929e1f48639362a2"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"1d3d8ed8ab8fe80184eb780262b5577cb26131a7b61b7e815737e9e412d8d4e6"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"f7c39813e719de53abbd4bd4dc99e3cc606253b3235ee04a9b346582bff771ce"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"1c03ed7644b8006a00b751ea3b97630e008e5896c3797ef0f1cb510b941c6234"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"6f9facafa101776ce7ddf4282a4f19edcfc40b76da251afa59f8e2f4350c9f33"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"21454ac9c648e0d130d40d1f15f9e909cf5c82eafa018e7a066a419b72cb0d41"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"8be4849f9c85c392d3e989d222d714169da982c0337d57cdc3411d14084d9bf3"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"583279e0360f529405948a6fb33712dabaa9917bb616bd00dcc83a6b6422827c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"8a45cab48d9f02da4fa2118e0a238696ab2f4ee198faff45ac64580c1f687d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"98edba7908cecffb141018bc358074f2785baf84bd76c4e9564843d48ad9e2dd"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"a7304f85f284dd0724475fed292a4ea17714b49061a0f6a6921d0d9899b1fa05"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"44e9ee4c29ba2276e2a8d946275e54aec0645f55cd9d63413ac16f59d1a68d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"694159395711268403159676c679a6a0d939bbaff546b673136f0ce4a67d686a"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"f4843da5a5fde4728e2dfe6766be0ce29b50a45af8a9508df8fcf86dffaee651"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"8463e5a981dcc4f67b386c5f1b97504905ef9a3fc7748992af8ac4e544ed0855"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"4c6785207b4216b2815068f68d438b3cbb6e480f684a661dc8f25d5e4b053e1b"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"5289188da20a1b4a9561cf814e0cc20dff38c1950d291892675948debc36a610"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"b4e6f8955890cf5188ed2227aebca561a2ff5e7b53e5d5363cdbb124b9b31702"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"b7a255452eb50e8b6cc3f3f589189d3c206c47395eed2aa6504d950ca7c69ea9"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"0d2d7067c8a8538fa40c6f0a68a666e65fa7a6f06f39de359e64ff30f752db5a"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"357cd413a37f173d51cacbdb6372d41b90b4d8d44787b6a2a456c7d4f4423336"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"7f21f53f2ba99894d65b3dee8518f9483805fc2bda9444939a5a1fa44d74df30"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"b66856473b10327fc5c661d684b773ca0e4674821130a3072f198d498f56d8e6"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"d4282ddc4619978d0a0cf76e898d9495fc058935832a42fc8a7a14c56fa1566a"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"ac0af152fad9c3d01f36aaf003c8bee4cb2ea7fed022e612ce21bcfe7160a98b"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22291,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"01259043d1891028cd61f5f4f3f29041ed58295bd43e5d147d8d1f1daca037ce"},{"bytes":1498199,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"9de6133a4be254740f94b7adc0f127d1944af08699816b4f78d4c8b7465843dd"},{"bytes":2362069,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"2db5083337425e528943c4eec837d81ff079c787573e41fe3b4610adad63111b"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1418551,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"0607539fd2c35038761f036925a92fa656e27ac45acdb23721e64882fe04d556"},{"bytes":3245077,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"f34c137c230bcc7b07cbc039ac7ee522a35c649851051cd171b09aecb04de523"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1282057,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"956ee3ba0344d53f4bdaa2fa08fc30968dd1f90ec203088c4bf76507db537a31"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads; --host and --model-provider are separate filters.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter: all (default) | local | hostId or friendly name","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Pass-through to app-server modelProviders (omit = all)","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter: all (default) | local | hostId or friendly name","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Pass-through to app-server modelProviders (omit = all)","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads; --host and --model-provider are separate filters.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"a7528652ca53097d55bc34f4cfa73b6315fd067ea572e7eda32112d0d9201e34","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index cb9bf64..ebb8cb6 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -8609,6 +8609,52 @@ var __webpack_modules__ = { resultSchema: resultSchema }); }, + "./src/cli/chatgpt-desktop/hosts.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const config = { + description: 'List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.', + exitCode: 'result', + inputJsonSchema: { + additionalProperties: false, + properties: { + port: { + description: 'Local CDP port', + type: 'number' + } + }, + type: 'object' + } + }; + const inputSchema = zod__rspack_import_2.Ikc({ + port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() + }).strict(); + async function chatgptDesktopHosts({ input }) { + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.Bm)(input); + const hosts = Array.isArray(out.hosts) ? out.hosts : []; + const text = hosts.length > 0 ? hosts.map((host)=>{ + const row = host; + const name = row.hostName && row.hostName !== row.hostId ? ` (${row.hostName})` : ''; + return `${row.hostId ?? '?'}${name} [${row.location ?? '?'}] threads=${row.threadCount ?? 0}`; + }).join('\n') + `\n\nhostsSource: ${String(out.hostsSource ?? '')}` + `\nmodelProviders: ${JSON.stringify(out.modelProviders ?? [])}` + `\nmodelProvidersSource: ${String(out.modelProvidersSource ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: text + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>chatgptDesktopHosts, + resultSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_1.FD + }, { + config: config, + inputSchema: inputSchema + }); + }, "./src/cli/chatgpt-desktop/read.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); @@ -8692,7 +8738,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.', + description: 'Search ChatGPT Desktop threads; --host and --model-provider are separate filters.', exitCode: 'result', positionals: [ 'query' @@ -8700,11 +8746,26 @@ var __webpack_modules__ = { inputJsonSchema: { additionalProperties: false, properties: { + groupBy: { + description: 'Group results by host', + enum: [ + 'host' + ], + type: 'string' + }, + host: { + description: 'Filter: all (default) | local | hostId or friendly name', + type: 'string' + }, limit: { default: 50, description: 'Max matches (1-200)', type: 'number' }, + modelProvider: { + description: 'Pass-through to app-server modelProviders (omit = all)', + type: 'string' + }, port: { description: 'Local CDP port', type: 'number' @@ -8720,7 +8781,10 @@ var __webpack_modules__ = { } }; const inputSchema = zod__rspack_import_2.Ikc({ + groupBy: zod__rspack_import_2.euz('host').optional(), + host: zod__rspack_import_2.YjP().min(1).max(256).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), + modelProvider: zod__rspack_import_2.YjP().min(1).max(256).optional(), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), query: zod__rspack_import_2.YjP().min(1).max(512) }).strict(); @@ -8861,7 +8925,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'List local + remote-control ChatGPT Desktop threads; optional --host and --group-by host.', + description: 'List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, @@ -8874,7 +8938,7 @@ var __webpack_modules__ = { type: 'string' }, host: { - description: 'Filter by hostId or friendly name (local for local-only)', + description: 'Filter: all (default) | local | hostId or friendly name', type: 'string' }, limit: { @@ -8882,6 +8946,10 @@ var __webpack_modules__ = { description: 'Max threads (1-200)', type: 'number' }, + modelProvider: { + description: 'Pass-through to app-server modelProviders (omit = all)', + type: 'string' + }, port: { description: 'Local CDP port', type: 'number' @@ -8894,6 +8962,7 @@ var __webpack_modules__ = { groupBy: zod__rspack_import_2.euz('host').optional(), host: zod__rspack_import_2.YjP().min(1).max(256).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), + modelProvider: zod__rspack_import_2.YjP().min(1).max(256).optional(), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() }).strict(); async function chatgptDesktopThreads({ input }) { @@ -8902,7 +8971,8 @@ var __webpack_modules__ = { const text = threads.length > 0 ? threads.map((thread)=>{ const row = thread; const where = row.location === 'remote' ? ` [remote ${row.hostName || row.hostId || '?'}]` : ' [local]'; - return `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : '') + where; + const provider = row.modelProvider ? ` {${row.modelProvider}}` : ''; + return `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : '') + where + provider; }).join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { value: out, @@ -11203,23 +11273,26 @@ var __webpack_modules__ = { var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _remote_threads_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); - async function appServerListThreads({ limit = 50, cursor } = {}) { + async function appServerListThreads({ limit = 50, cursor, modelProviders = [] } = {}) { const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit, - cursor + cursor, + modelProviders }); return { backend: 'app-server', limit: out.limit, nextCursor: out.nextCursor ?? null, - threads: out.threads.map(mapListedThread) + threads: out.threads.map(mapListedThread), + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } - async function appServerSearchThreads({ query, limit = 50 }) { + async function appServerSearchThreads({ query, limit = 50, modelProviders = [] }) { const needle = query.trim().toLowerCase(); if (!needle) { return appServerListThreads({ - limit + limit, + modelProviders }); } const matched = []; @@ -11227,7 +11300,8 @@ var __webpack_modules__ = { for(let page = 0; page < 20 && matched.length < limit; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit: 200, - cursor + cursor, + modelProviders }); for (const thread of out.threads){ const mapped = mapListedThread(thread); @@ -11242,9 +11316,180 @@ var __webpack_modules__ = { limit, query, nextCursor: null, - threads: matched.slice(0, limit) + threads: matched.slice(0, limit), + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined + }; + } + const MODEL_PROVIDER_LIST_METHODS = [ + 'modelProvider/list', + 'model/providers/list', + 'models/providers/list', + 'account/modelProviders/list', + 'config/modelProviders/list', + 'provider/list' + ]; + const REMOTE_ENVIRONMENT_LIST_METHODS = [ + 'remoteEnvironment/list', + 'remote/environments/list', + 'environment/list', + 'remoteControl/hosts/list', + 'remote/hosts/list', + 'hosts/list' + ]; + async function discoverModelProviders() { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + for (const method of MODEL_PROVIDER_LIST_METHODS){ + try { + const result = await client.request(method, {}); + const providers = normalizeNamedList(result, [ + 'id', + 'name', + 'provider', + 'modelProvider', + 'slug' + ]); + if (providers.length > 0) { + return { + providers, + source: `app-server:${method}` + }; + } + } catch {} + } + } finally{ + client.close(); + } + const providers = new Set(); + let cursor; + for(let page = 0; page < 20; page++){ + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit: 200, + cursor, + modelProviders: [] + }); + for (const thread of out.threads){ + if (typeof thread.modelProvider === 'string' && thread.modelProvider) { + providers.add(thread.modelProvider); + } + } + if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + cursor = out.nextCursor; + } + return { + providers: [ + ...providers + ].sort(), + source: 'thread/list-distinct' + }; + } + async function discoverRemoteEnvironments() { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + for (const method of REMOTE_ENVIRONMENT_LIST_METHODS){ + try { + const result = await client.request(method, {}); + const hosts = normalizeHostEntries(result); + if (hosts.length > 0) { + return { + hosts, + source: `app-server:${method}` + }; + } + } catch {} + } + } finally{ + client.close(); + } + return { + hosts: [], + source: null }; } + function normalizeNamedList(result, idKeys) { + const raw = listPayload(result); + const out = []; + for (const entry of raw){ + if (typeof entry === 'string' && entry) out.push(entry); + else if (entry && typeof entry === 'object') { + const row = entry; + for (const key of idKeys){ + if (typeof row[key] === 'string' && row[key]) { + out.push(String(row[key])); + break; + } + } + } + } + return [ + ...new Set(out) + ].sort(); + } + function normalizeHostEntries(result) { + const raw = listPayload(result); + const out = []; + for (const entry of raw){ + if (typeof entry === 'string' && entry) { + out.push({ + hostId: entry, + hostName: null + }); + continue; + } + if (!entry || typeof entry !== 'object') continue; + const row = entry; + let hostId = null; + for (const key of [ + 'hostId', + 'id', + 'uuid', + 'environmentId', + 'envId' + ]){ + if (typeof row[key] === 'string' && row[key]) { + hostId = String(row[key]); + break; + } + } + if (!hostId) continue; + let hostName = null; + for (const key of [ + 'hostName', + 'name', + 'displayName', + 'envName', + 'label', + 'title' + ]){ + if (typeof row[key] === 'string' && row[key]) { + hostName = String(row[key]); + break; + } + } + out.push({ + hostId, + hostName + }); + } + return out; + } + function listPayload(result) { + if (Array.isArray(result)) return result; + if (!result || typeof result !== 'object') return []; + const record = result; + for (const key of [ + 'data', + 'providers', + 'modelProviders', + 'hosts', + 'environments', + 'remoteEnvironments', + 'items' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + return []; + } async function appServerReadThread({ threadId, limit = 100, full = false }) { const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); @@ -11570,6 +11815,8 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, + OP: ()=>discoverRemoteEnvironments, + X: ()=>discoverModelProviders, aI: ()=>appServerSearchThreads, dM: ()=>appServerStatusProbe }); @@ -12482,7 +12729,10 @@ var __webpack_modules__ = { searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, statusProbe: _app_server_fallback_js__rspack_import_1.dM, - listRemoteThreads: _remote_threads_js__rspack_import_4.Hx + listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, + listHosts: _remote_threads_js__rspack_import_4.Kl, + discoverModelProviders: _app_server_fallback_js__rspack_import_1.X, + discoverRemoteEnvironments: _app_server_fallback_js__rspack_import_1.OP }; class ChatGptDesktopFacade { #cdp; @@ -12512,11 +12762,14 @@ var __webpack_modules__ = { } async listThreads(options = {}) { const limit = options.limit ?? 50; + const host = normalizeHostFilter(options.host); + const modelProviders = modelProvidersFromFilter(options.modelProvider); let appList = null; let appError; try { appList = await this.#fallbacks.listThreads({ - limit + limit, + modelProviders }); } catch (error) { appError = error; @@ -12544,17 +12797,107 @@ var __webpack_modules__ = { else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); return finalizeThreadList(base, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: this.#listRemotes() }); } + async listHosts() { + const remotes = this.#listRemotes(); + let localThreadCount = 0; + try { + const local = await this.#fallbacks.listThreads({ + limit: 200, + modelProviders: [] + }); + localThreadCount = local.threads.length; + } catch { + localThreadCount = 0; + } + const listHosts = this.#fallbacks.listHosts ?? _remote_threads_js__rspack_import_4.Kl; + const fromState = listHosts(process.env, { + localThreadCount + }); + const byId = new Map(fromState.map((host)=>[ + host.hostId, + { + ...host + } + ])); + let hostsSource = 'remote-thread-summaries-v3+local'; + try { + const discoverEnvs = this.#fallbacks.discoverRemoteEnvironments ?? _app_server_fallback_js__rspack_import_1.OP; + const appHosts = await discoverEnvs(); + if (appHosts.source && appHosts.hosts.length > 0) { + for (const host of appHosts.hosts){ + const existing = byId.get(host.hostId); + if (existing) { + byId.set(host.hostId, { + ...existing, + hostName: existing.hostName ?? host.hostName + }); + } else { + byId.set(host.hostId, { + hostId: host.hostId, + hostName: host.hostName, + location: 'remote', + threadCount: 0 + }); + } + } + hostsSource = `${appHosts.source}+remote-thread-summaries-v3+local`; + } + } catch {} + const remoteCounts = new Map(); + for (const thread of remotes){ + remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + } + const withCounts = [ + ...byId.values() + ].map((host)=>host.hostId === 'local' ? { + ...host, + threadCount: localThreadCount + } : { + ...host, + threadCount: remoteCounts.get(host.hostId) ?? host.threadCount + }).sort((a, b)=>{ + if (a.hostId === 'local') return -1; + if (b.hostId === 'local') return 1; + return a.hostId.localeCompare(b.hostId); + }); + let modelProviders = []; + let modelProvidersSource = 'thread/list-distinct'; + try { + const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_1.X; + const discovered = await discover(); + modelProviders = [ + ...discovered.providers + ]; + modelProvidersSource = discovered.source; + } catch { + modelProviders = [ + ...new Set(remotes.map((thread)=>thread.modelProvider).filter((value)=>typeof value === 'string' && Boolean(value))) + ].sort(); + modelProvidersSource = 'remote-summaries-distinct'; + } + return { + hosts: withCounts, + hostsSource, + modelProviders, + modelProvidersSource, + backend: 'app-server' + }; + } async searchThreads(options) { const limit = options.limit ?? 50; + const host = normalizeHostFilter(options.host); + const modelProviders = modelProvidersFromFilter(options.modelProvider); try { const appList = await this.#fallbacks.searchThreads({ query: options.query, - limit + limit, + modelProviders }); const cdpList = await this.#tryCdpList({ limit @@ -12562,7 +12905,8 @@ var __webpack_modules__ = { const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; const withRemotes = finalizeThreadList(base, { limit: 10000, - host: options.host, + host, + modelProvider: options.modelProvider, remotes: this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); @@ -12573,7 +12917,8 @@ var __webpack_modules__ = { }; return finalizeThreadList(filtered, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: [] }); @@ -12590,7 +12935,8 @@ var __webpack_modules__ = { }; return finalizeThreadList(filtered, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: this.#listRemotes() }); @@ -12742,7 +13088,7 @@ var __webpack_modules__ = { threads: merged }; } - function finalizeThreadList(base, { limit, host, groupBy, remotes }) { + function finalizeThreadList(base, { limit, host = 'all', modelProvider, groupBy, remotes }) { const locals = base.threads.map((thread)=>{ const location = thread.location ?? 'local'; return { @@ -12766,7 +13112,11 @@ var __webpack_modules__ = { hostName: remote.hostName ?? null }); } - const filtered = host ? merged.filter((thread)=>hostMatches(thread, host)) : merged; + const filtered = merged.filter((thread)=>{ + if (!hostMatches(thread, host)) return false; + if (!modelProviderMatches(thread, modelProvider)) return false; + return true; + }); const limited = filtered.slice(0, limit); const result = { backend: base.backend, @@ -12778,8 +13128,9 @@ var __webpack_modules__ = { ...base.query !== undefined ? { query: base.query } : {}, - ...host ? { - host + host, + ...modelProvider ? { + modelProvider } : {} }; if (groupBy === 'host') { @@ -12815,15 +13166,32 @@ var __webpack_modules__ = { ...groups.values() ]; } + function normalizeHostFilter(host) { + const value = (host ?? 'all').trim(); + return value || 'all'; + } + function modelProvidersFromFilter(modelProvider) { + if (!modelProvider || !modelProvider.trim()) return []; + return [ + modelProvider.trim() + ]; + } function hostMatches(thread, host) { const needle = host.trim().toLowerCase(); - if (!needle) return true; + if (!needle || needle === 'all') return true; if (needle === 'local') return (thread.location ?? 'local') === 'local'; return [ thread.hostId, thread.hostName ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); } + function modelProviderMatches(thread, modelProvider) { + if (!modelProvider) return true; + if (!thread.modelProvider) { + return thread.location === 'remote'; + } + return thread.modelProvider === modelProvider; + } function threadMatchesQuery(thread, needle) { if (!needle) return true; return [ @@ -12988,6 +13356,57 @@ var __webpack_modules__ = { function findRemoteThreadHostId(threadId, env = process.env) { return findRemoteThread(threadId, env)?.hostId ?? null; } + function listDiscoveredHosts(env = process.env, { localThreadCount = 0 } = {}) { + const remotes = listRemoteThreadsFromState(env); + const byHost = new Map(); + byHost.set('local', { + hostId: 'local', + hostName: 'local', + location: 'local', + threadCount: localThreadCount + }); + const data = loadCodexGlobalState(env); + if (data) { + const hostNames = collectHostNames(data); + for (const key of Object.keys(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match?.[1]) continue; + const hostId = match[1]; + const summary = data[key]; + const hostName = hostNames.get(hostId) ?? extractHostName(summary) ?? null; + byHost.set(hostId, { + hostId, + hostName, + location: 'remote', + threadCount: 0 + }); + } + } + for (const thread of remotes){ + const existing = byHost.get(thread.hostId); + if (existing) { + byHost.set(thread.hostId, { + ...existing, + hostName: existing.hostName ?? thread.hostName, + threadCount: existing.threadCount + 1 + }); + } else { + byHost.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName, + location: 'remote', + threadCount: 1 + }); + } + } + return [ + ...byHost.values() + ].sort((a, b)=>{ + if (a.hostId === 'local') return -1; + if (b.hostId === 'local') return 1; + return a.hostId.localeCompare(b.hostId); + }); + } function collectHostNames(data) { const names = new Map(); for (const [key, value] of Object.entries(data)){ @@ -13276,6 +13695,7 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Hx: ()=>listRemoteThreadsFromState, KI: ()=>findRemoteThread, + Kl: ()=>listDiscoveredHosts, XI: ()=>findRemoteThreadHostId }); }, @@ -13293,6 +13713,7 @@ var __webpack_modules__ = { port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const searchThreadsSchema = zod__rspack_import_4.Ikc({ @@ -13300,8 +13721,12 @@ var __webpack_modules__ = { query: zod__rspack_import_4.YjP().min(1).max(512), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); + const listHostsSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional() + }).strict(); const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, @@ -13390,6 +13815,7 @@ var __webpack_modules__ = { const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ limit: input.limit, host: input.host, + modelProvider: input.modelProvider, groupBy: input.groupBy })); return asResult({ @@ -13410,6 +13836,7 @@ var __webpack_modules__ = { query: input.query, limit: input.limit, host: input.host, + modelProvider: input.modelProvider, groupBy: input.groupBy }); }); @@ -13421,6 +13848,22 @@ var __webpack_modules__ = { return mapError(error); } } + async function listHostsOperation(input) { + try { + const out = await withAdapter(input.port, async (adapter)=>{ + if (typeof adapter.listHosts !== 'function') { + throw new _errors_js__rspack_import_1.EH('listHosts', 'adapter does not implement listHosts'); + } + return adapter.listHosts(); + }); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } async function readThreadOperation(input) { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ @@ -13474,9 +13917,15 @@ var __webpack_modules__ = { return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); + if (Array.isArray(result.hosts)) { + const providers = Array.isArray(result.modelProviders) ? ` providers=${result.modelProviders.length} (${String(result.modelProvidersSource ?? '')})` : ''; + return `${result.hosts.length} hosts via ${String(result.hostsSource ?? result.backend ?? 'unknown')}${providers}`; + } if (Array.isArray(result.threads)) { const via = result.query ? ` matching ${JSON.stringify(result.query)}` : ''; - return `${result.threads.length} threads${via} via ${result.backend ?? 'unknown'}`; + const host = result.host && result.host !== 'all' ? ` host=${result.host}` : ''; + const provider = result.modelProvider ? ` provider=${result.modelProvider}` : ''; + return `${result.threads.length} threads${via}${host}${provider} via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { const mode = result.full ? 'full' : 'page'; @@ -13493,6 +13942,7 @@ var __webpack_modules__ = { return JSON.stringify(result); } __webpack_require__.d(__webpack_exports__, { + Bm: ()=>listHostsOperation, D6: ()=>resultText, UK: ()=>readThreadOperation, UP: ()=>sendOperation, @@ -25312,17 +25762,20 @@ var __webpack_modules__ = { }; } const THREAD_LIST_MAX_LIMIT = 200; - async function listCodexThreads1({ limit = 20, cursor, env = process.env } = {}) { + async function listCodexThreads1({ limit = 20, cursor, modelProviders = [], env = process.env } = {}) { if (!Number.isInteger(limit) || limit < 1 || limit > THREAD_LIST_MAX_LIMIT) { throw new RangeError("--limit must be an integer 1-" + THREAD_LIST_MAX_LIMIT); } if (cursor !== undefined && (typeof cursor !== "string" || !cursor)) throw new RangeError("--cursor must be a non-empty string"); + if (!Array.isArray(modelProviders) || modelProviders.some((p)=>typeof p !== "string")) { + throw new RangeError("modelProviders must be an array of strings (empty = all providers)"); + } const { client } = await openSession(env); try { const params = { limit, useStateDbOnly: true, - modelProviders: [], + modelProviders, ...cursor !== undefined ? { cursor } : {} @@ -28610,9 +29063,9 @@ function __webpack_require__(moduleId) { var __webpack_exports__ = {}; var node_worker_threads__rspack_import_0 = __webpack_require__("node:worker_threads"); var react__rspack_import_1 = __webpack_require__("./node_modules/react/react.react-server.js"); -var _agent_bundle_runtime_flight_server__rspack_import_46 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); -var _agent_bundle_runtime__rspack_import_44 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); -var _agent_bundle_runtime__rspack_import_45 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); +var _agent_bundle_runtime_flight_server__rspack_import_47 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); +var _agent_bundle_runtime__rspack_import_45 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); +var _agent_bundle_runtime__rspack_import_46 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); var node_url__rspack_import_2 = __webpack_require__("node:url"); var _src_cli_approvals_list_tsx__rspack_import_3 = __webpack_require__("./src/cli/approvals/list.tsx"); var _src_cli_approvals_respond_tsx__rspack_import_4 = __webpack_require__("./src/cli/approvals/respond.tsx"); @@ -28621,40 +29074,41 @@ var _src_cli_bots_delete_tsx__rspack_import_6 = __webpack_require__("./src/cli/b var _src_cli_bots_get_tsx__rspack_import_7 = __webpack_require__("./src/cli/bots/get.tsx"); var _src_cli_bots_list_tsx__rspack_import_8 = __webpack_require__("./src/cli/bots/list.tsx"); var _src_cli_bots_update_tsx__rspack_import_9 = __webpack_require__("./src/cli/bots/update.tsx"); -var _src_cli_chatgpt_desktop_read_tsx__rspack_import_10 = __webpack_require__("./src/cli/chatgpt-desktop/read.tsx"); -var _src_cli_chatgpt_desktop_search_tsx__rspack_import_11 = __webpack_require__("./src/cli/chatgpt-desktop/search.tsx"); -var _src_cli_chatgpt_desktop_send_tsx__rspack_import_12 = __webpack_require__("./src/cli/chatgpt-desktop/send.tsx"); -var _src_cli_chatgpt_desktop_status_tsx__rspack_import_13 = __webpack_require__("./src/cli/chatgpt-desktop/status.tsx"); -var _src_cli_chatgpt_desktop_threads_tsx__rspack_import_14 = __webpack_require__("./src/cli/chatgpt-desktop/threads.tsx"); -var _src_cli_claude_send_tsx__rspack_import_15 = __webpack_require__("./src/cli/claude/send.tsx"); -var _src_cli_codex_bridge_respond_tsx__rspack_import_16 = __webpack_require__("./src/cli/codex/bridge/respond.tsx"); -var _src_cli_codex_bridge_run_tsx__rspack_import_17 = __webpack_require__("./src/cli/codex/bridge/run.tsx"); -var _src_cli_codex_bridge_start_tsx__rspack_import_18 = __webpack_require__("./src/cli/codex/bridge/start.tsx"); -var _src_cli_codex_bridge_status_tsx__rspack_import_19 = __webpack_require__("./src/cli/codex/bridge/status.tsx"); -var _src_cli_codex_bridge_stop_tsx__rspack_import_20 = __webpack_require__("./src/cli/codex/bridge/stop.tsx"); -var _src_cli_codex_desktop_shim_tsx__rspack_import_21 = __webpack_require__("./src/cli/codex/desktop-shim.tsx"); -var _src_cli_codex_list_threads_tsx__rspack_import_22 = __webpack_require__("./src/cli/codex/list-threads.tsx"); -var _src_cli_codex_queue_tsx__rspack_import_23 = __webpack_require__("./src/cli/codex/queue.tsx"); -var _src_cli_codex_send_tsx__rspack_import_24 = __webpack_require__("./src/cli/codex/send.tsx"); -var _src_cli_codex_status_tsx__rspack_import_25 = __webpack_require__("./src/cli/codex/status.tsx"); -var _src_cli_codex_wait_tsx__rspack_import_26 = __webpack_require__("./src/cli/codex/wait.tsx"); -var _src_cli_codex_watch_tsx__rspack_import_27 = __webpack_require__("./src/cli/codex/watch.tsx"); -var _src_cli_doctor_tsx__rspack_import_28 = __webpack_require__("./src/cli/doctor.tsx"); -var _src_cli_groups_add_tsx__rspack_import_29 = __webpack_require__("./src/cli/groups/add.tsx"); -var _src_cli_groups_create_tsx__rspack_import_30 = __webpack_require__("./src/cli/groups/create.tsx"); -var _src_cli_groups_delete_tsx__rspack_import_31 = __webpack_require__("./src/cli/groups/delete.tsx"); -var _src_cli_groups_get_tsx__rspack_import_32 = __webpack_require__("./src/cli/groups/get.tsx"); -var _src_cli_groups_list_tsx__rspack_import_33 = __webpack_require__("./src/cli/groups/list.tsx"); -var _src_cli_groups_members_tsx__rspack_import_34 = __webpack_require__("./src/cli/groups/members.tsx"); -var _src_cli_groups_remove_tsx__rspack_import_35 = __webpack_require__("./src/cli/groups/remove.tsx"); -var _src_cli_groups_set_tsx__rspack_import_36 = __webpack_require__("./src/cli/groups/set.tsx"); -var _src_cli_groups_update_tsx__rspack_import_37 = __webpack_require__("./src/cli/groups/update.tsx"); -var _src_cli_history_tsx__rspack_import_38 = __webpack_require__("./src/cli/history.tsx"); -var _src_cli_send_tsx__rspack_import_39 = __webpack_require__("./src/cli/send.tsx"); -var _src_cli_skills_add_tsx__rspack_import_40 = __webpack_require__("./src/cli/skills/add.tsx"); -var _src_cli_skills_list_tsx__rspack_import_41 = __webpack_require__("./src/cli/skills/list.tsx"); -var _src_cli_skills_remove_tsx__rspack_import_42 = __webpack_require__("./src/cli/skills/remove.tsx"); -var _src_cli_thread_tsx__rspack_import_43 = __webpack_require__("./src/cli/thread.tsx"); +var _src_cli_chatgpt_desktop_hosts_tsx__rspack_import_10 = __webpack_require__("./src/cli/chatgpt-desktop/hosts.tsx"); +var _src_cli_chatgpt_desktop_read_tsx__rspack_import_11 = __webpack_require__("./src/cli/chatgpt-desktop/read.tsx"); +var _src_cli_chatgpt_desktop_search_tsx__rspack_import_12 = __webpack_require__("./src/cli/chatgpt-desktop/search.tsx"); +var _src_cli_chatgpt_desktop_send_tsx__rspack_import_13 = __webpack_require__("./src/cli/chatgpt-desktop/send.tsx"); +var _src_cli_chatgpt_desktop_status_tsx__rspack_import_14 = __webpack_require__("./src/cli/chatgpt-desktop/status.tsx"); +var _src_cli_chatgpt_desktop_threads_tsx__rspack_import_15 = __webpack_require__("./src/cli/chatgpt-desktop/threads.tsx"); +var _src_cli_claude_send_tsx__rspack_import_16 = __webpack_require__("./src/cli/claude/send.tsx"); +var _src_cli_codex_bridge_respond_tsx__rspack_import_17 = __webpack_require__("./src/cli/codex/bridge/respond.tsx"); +var _src_cli_codex_bridge_run_tsx__rspack_import_18 = __webpack_require__("./src/cli/codex/bridge/run.tsx"); +var _src_cli_codex_bridge_start_tsx__rspack_import_19 = __webpack_require__("./src/cli/codex/bridge/start.tsx"); +var _src_cli_codex_bridge_status_tsx__rspack_import_20 = __webpack_require__("./src/cli/codex/bridge/status.tsx"); +var _src_cli_codex_bridge_stop_tsx__rspack_import_21 = __webpack_require__("./src/cli/codex/bridge/stop.tsx"); +var _src_cli_codex_desktop_shim_tsx__rspack_import_22 = __webpack_require__("./src/cli/codex/desktop-shim.tsx"); +var _src_cli_codex_list_threads_tsx__rspack_import_23 = __webpack_require__("./src/cli/codex/list-threads.tsx"); +var _src_cli_codex_queue_tsx__rspack_import_24 = __webpack_require__("./src/cli/codex/queue.tsx"); +var _src_cli_codex_send_tsx__rspack_import_25 = __webpack_require__("./src/cli/codex/send.tsx"); +var _src_cli_codex_status_tsx__rspack_import_26 = __webpack_require__("./src/cli/codex/status.tsx"); +var _src_cli_codex_wait_tsx__rspack_import_27 = __webpack_require__("./src/cli/codex/wait.tsx"); +var _src_cli_codex_watch_tsx__rspack_import_28 = __webpack_require__("./src/cli/codex/watch.tsx"); +var _src_cli_doctor_tsx__rspack_import_29 = __webpack_require__("./src/cli/doctor.tsx"); +var _src_cli_groups_add_tsx__rspack_import_30 = __webpack_require__("./src/cli/groups/add.tsx"); +var _src_cli_groups_create_tsx__rspack_import_31 = __webpack_require__("./src/cli/groups/create.tsx"); +var _src_cli_groups_delete_tsx__rspack_import_32 = __webpack_require__("./src/cli/groups/delete.tsx"); +var _src_cli_groups_get_tsx__rspack_import_33 = __webpack_require__("./src/cli/groups/get.tsx"); +var _src_cli_groups_list_tsx__rspack_import_34 = __webpack_require__("./src/cli/groups/list.tsx"); +var _src_cli_groups_members_tsx__rspack_import_35 = __webpack_require__("./src/cli/groups/members.tsx"); +var _src_cli_groups_remove_tsx__rspack_import_36 = __webpack_require__("./src/cli/groups/remove.tsx"); +var _src_cli_groups_set_tsx__rspack_import_37 = __webpack_require__("./src/cli/groups/set.tsx"); +var _src_cli_groups_update_tsx__rspack_import_38 = __webpack_require__("./src/cli/groups/update.tsx"); +var _src_cli_history_tsx__rspack_import_39 = __webpack_require__("./src/cli/history.tsx"); +var _src_cli_send_tsx__rspack_import_40 = __webpack_require__("./src/cli/send.tsx"); +var _src_cli_skills_add_tsx__rspack_import_41 = __webpack_require__("./src/cli/skills/add.tsx"); +var _src_cli_skills_list_tsx__rspack_import_42 = __webpack_require__("./src/cli/skills/list.tsx"); +var _src_cli_skills_remove_tsx__rspack_import_43 = __webpack_require__("./src/cli/skills/remove.tsx"); +var _src_cli_thread_tsx__rspack_import_44 = __webpack_require__("./src/cli/thread.tsx"); const route0 = Object.assign({}, Reflect.get(_src_cli_approvals_list_tsx__rspack_import_3, 'default'), _src_cli_approvals_list_tsx__rspack_import_3); const route1 = Object.assign({}, Reflect.get(_src_cli_approvals_respond_tsx__rspack_import_4, 'default'), _src_cli_approvals_respond_tsx__rspack_import_4); const route2 = Object.assign({}, Reflect.get(_src_cli_bots_create_tsx__rspack_import_5, 'default'), _src_cli_bots_create_tsx__rspack_import_5); @@ -28662,41 +29116,42 @@ const route3 = Object.assign({}, Reflect.get(_src_cli_bots_delete_tsx__rspack_im const route4 = Object.assign({}, Reflect.get(_src_cli_bots_get_tsx__rspack_import_7, 'default'), _src_cli_bots_get_tsx__rspack_import_7); const route5 = Object.assign({}, Reflect.get(_src_cli_bots_list_tsx__rspack_import_8, 'default'), _src_cli_bots_list_tsx__rspack_import_8); const route6 = Object.assign({}, Reflect.get(_src_cli_bots_update_tsx__rspack_import_9, 'default'), _src_cli_bots_update_tsx__rspack_import_9); -const route7 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_read_tsx__rspack_import_10, 'default'), _src_cli_chatgpt_desktop_read_tsx__rspack_import_10); -const route8 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_search_tsx__rspack_import_11, 'default'), _src_cli_chatgpt_desktop_search_tsx__rspack_import_11); -const route9 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_send_tsx__rspack_import_12, 'default'), _src_cli_chatgpt_desktop_send_tsx__rspack_import_12); -const route10 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_status_tsx__rspack_import_13, 'default'), _src_cli_chatgpt_desktop_status_tsx__rspack_import_13); -const route11 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_threads_tsx__rspack_import_14, 'default'), _src_cli_chatgpt_desktop_threads_tsx__rspack_import_14); -const route12 = Object.assign({}, Reflect.get(_src_cli_claude_send_tsx__rspack_import_15, 'default'), _src_cli_claude_send_tsx__rspack_import_15); -const route13 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_respond_tsx__rspack_import_16, 'default'), _src_cli_codex_bridge_respond_tsx__rspack_import_16); -const route14 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_run_tsx__rspack_import_17, 'default'), _src_cli_codex_bridge_run_tsx__rspack_import_17); -const route15 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_start_tsx__rspack_import_18, 'default'), _src_cli_codex_bridge_start_tsx__rspack_import_18); -const route16 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_status_tsx__rspack_import_19, 'default'), _src_cli_codex_bridge_status_tsx__rspack_import_19); -const route17 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_stop_tsx__rspack_import_20, 'default'), _src_cli_codex_bridge_stop_tsx__rspack_import_20); -const route18 = Object.assign({}, Reflect.get(_src_cli_codex_desktop_shim_tsx__rspack_import_21, 'default'), _src_cli_codex_desktop_shim_tsx__rspack_import_21); -const route19 = Object.assign({}, Reflect.get(_src_cli_codex_list_threads_tsx__rspack_import_22, 'default'), _src_cli_codex_list_threads_tsx__rspack_import_22); -const route20 = Object.assign({}, Reflect.get(_src_cli_codex_queue_tsx__rspack_import_23, 'default'), _src_cli_codex_queue_tsx__rspack_import_23); -const route21 = Object.assign({}, Reflect.get(_src_cli_codex_send_tsx__rspack_import_24, 'default'), _src_cli_codex_send_tsx__rspack_import_24); -const route22 = Object.assign({}, Reflect.get(_src_cli_codex_status_tsx__rspack_import_25, 'default'), _src_cli_codex_status_tsx__rspack_import_25); -const route23 = Object.assign({}, Reflect.get(_src_cli_codex_wait_tsx__rspack_import_26, 'default'), _src_cli_codex_wait_tsx__rspack_import_26); -const route24 = Object.assign({}, Reflect.get(_src_cli_codex_watch_tsx__rspack_import_27, 'default'), _src_cli_codex_watch_tsx__rspack_import_27); -const route25 = Object.assign({}, Reflect.get(_src_cli_doctor_tsx__rspack_import_28, 'default'), _src_cli_doctor_tsx__rspack_import_28); -const route26 = Object.assign({}, Reflect.get(_src_cli_groups_add_tsx__rspack_import_29, 'default'), _src_cli_groups_add_tsx__rspack_import_29); -const route27 = Object.assign({}, Reflect.get(_src_cli_groups_create_tsx__rspack_import_30, 'default'), _src_cli_groups_create_tsx__rspack_import_30); -const route28 = Object.assign({}, Reflect.get(_src_cli_groups_delete_tsx__rspack_import_31, 'default'), _src_cli_groups_delete_tsx__rspack_import_31); -const route29 = Object.assign({}, Reflect.get(_src_cli_groups_get_tsx__rspack_import_32, 'default'), _src_cli_groups_get_tsx__rspack_import_32); -const route30 = Object.assign({}, Reflect.get(_src_cli_groups_list_tsx__rspack_import_33, 'default'), _src_cli_groups_list_tsx__rspack_import_33); -const route31 = Object.assign({}, Reflect.get(_src_cli_groups_members_tsx__rspack_import_34, 'default'), _src_cli_groups_members_tsx__rspack_import_34); -const route32 = Object.assign({}, Reflect.get(_src_cli_groups_remove_tsx__rspack_import_35, 'default'), _src_cli_groups_remove_tsx__rspack_import_35); -const route33 = Object.assign({}, Reflect.get(_src_cli_groups_set_tsx__rspack_import_36, 'default'), _src_cli_groups_set_tsx__rspack_import_36); -const route34 = Object.assign({}, Reflect.get(_src_cli_groups_update_tsx__rspack_import_37, 'default'), _src_cli_groups_update_tsx__rspack_import_37); -const route35 = Object.assign({}, Reflect.get(_src_cli_history_tsx__rspack_import_38, 'default'), _src_cli_history_tsx__rspack_import_38); -const route36 = Object.assign({}, Reflect.get(_src_cli_send_tsx__rspack_import_39, 'default'), _src_cli_send_tsx__rspack_import_39); -const route37 = Object.assign({}, Reflect.get(_src_cli_skills_add_tsx__rspack_import_40, 'default'), _src_cli_skills_add_tsx__rspack_import_40); -const route38 = Object.assign({}, Reflect.get(_src_cli_skills_list_tsx__rspack_import_41, 'default'), _src_cli_skills_list_tsx__rspack_import_41); -const route39 = Object.assign({}, Reflect.get(_src_cli_skills_remove_tsx__rspack_import_42, 'default'), _src_cli_skills_remove_tsx__rspack_import_42); -const route40 = Object.assign({}, Reflect.get(_src_cli_thread_tsx__rspack_import_43, 'default'), _src_cli_thread_tsx__rspack_import_43); -const pluginRoot = (0, _agent_bundle_runtime__rspack_import_44.E7)({ +const route7 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_hosts_tsx__rspack_import_10, 'default'), _src_cli_chatgpt_desktop_hosts_tsx__rspack_import_10); +const route8 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_read_tsx__rspack_import_11, 'default'), _src_cli_chatgpt_desktop_read_tsx__rspack_import_11); +const route9 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_search_tsx__rspack_import_12, 'default'), _src_cli_chatgpt_desktop_search_tsx__rspack_import_12); +const route10 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_send_tsx__rspack_import_13, 'default'), _src_cli_chatgpt_desktop_send_tsx__rspack_import_13); +const route11 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_status_tsx__rspack_import_14, 'default'), _src_cli_chatgpt_desktop_status_tsx__rspack_import_14); +const route12 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_threads_tsx__rspack_import_15, 'default'), _src_cli_chatgpt_desktop_threads_tsx__rspack_import_15); +const route13 = Object.assign({}, Reflect.get(_src_cli_claude_send_tsx__rspack_import_16, 'default'), _src_cli_claude_send_tsx__rspack_import_16); +const route14 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_respond_tsx__rspack_import_17, 'default'), _src_cli_codex_bridge_respond_tsx__rspack_import_17); +const route15 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_run_tsx__rspack_import_18, 'default'), _src_cli_codex_bridge_run_tsx__rspack_import_18); +const route16 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_start_tsx__rspack_import_19, 'default'), _src_cli_codex_bridge_start_tsx__rspack_import_19); +const route17 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_status_tsx__rspack_import_20, 'default'), _src_cli_codex_bridge_status_tsx__rspack_import_20); +const route18 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_stop_tsx__rspack_import_21, 'default'), _src_cli_codex_bridge_stop_tsx__rspack_import_21); +const route19 = Object.assign({}, Reflect.get(_src_cli_codex_desktop_shim_tsx__rspack_import_22, 'default'), _src_cli_codex_desktop_shim_tsx__rspack_import_22); +const route20 = Object.assign({}, Reflect.get(_src_cli_codex_list_threads_tsx__rspack_import_23, 'default'), _src_cli_codex_list_threads_tsx__rspack_import_23); +const route21 = Object.assign({}, Reflect.get(_src_cli_codex_queue_tsx__rspack_import_24, 'default'), _src_cli_codex_queue_tsx__rspack_import_24); +const route22 = Object.assign({}, Reflect.get(_src_cli_codex_send_tsx__rspack_import_25, 'default'), _src_cli_codex_send_tsx__rspack_import_25); +const route23 = Object.assign({}, Reflect.get(_src_cli_codex_status_tsx__rspack_import_26, 'default'), _src_cli_codex_status_tsx__rspack_import_26); +const route24 = Object.assign({}, Reflect.get(_src_cli_codex_wait_tsx__rspack_import_27, 'default'), _src_cli_codex_wait_tsx__rspack_import_27); +const route25 = Object.assign({}, Reflect.get(_src_cli_codex_watch_tsx__rspack_import_28, 'default'), _src_cli_codex_watch_tsx__rspack_import_28); +const route26 = Object.assign({}, Reflect.get(_src_cli_doctor_tsx__rspack_import_29, 'default'), _src_cli_doctor_tsx__rspack_import_29); +const route27 = Object.assign({}, Reflect.get(_src_cli_groups_add_tsx__rspack_import_30, 'default'), _src_cli_groups_add_tsx__rspack_import_30); +const route28 = Object.assign({}, Reflect.get(_src_cli_groups_create_tsx__rspack_import_31, 'default'), _src_cli_groups_create_tsx__rspack_import_31); +const route29 = Object.assign({}, Reflect.get(_src_cli_groups_delete_tsx__rspack_import_32, 'default'), _src_cli_groups_delete_tsx__rspack_import_32); +const route30 = Object.assign({}, Reflect.get(_src_cli_groups_get_tsx__rspack_import_33, 'default'), _src_cli_groups_get_tsx__rspack_import_33); +const route31 = Object.assign({}, Reflect.get(_src_cli_groups_list_tsx__rspack_import_34, 'default'), _src_cli_groups_list_tsx__rspack_import_34); +const route32 = Object.assign({}, Reflect.get(_src_cli_groups_members_tsx__rspack_import_35, 'default'), _src_cli_groups_members_tsx__rspack_import_35); +const route33 = Object.assign({}, Reflect.get(_src_cli_groups_remove_tsx__rspack_import_36, 'default'), _src_cli_groups_remove_tsx__rspack_import_36); +const route34 = Object.assign({}, Reflect.get(_src_cli_groups_set_tsx__rspack_import_37, 'default'), _src_cli_groups_set_tsx__rspack_import_37); +const route35 = Object.assign({}, Reflect.get(_src_cli_groups_update_tsx__rspack_import_38, 'default'), _src_cli_groups_update_tsx__rspack_import_38); +const route36 = Object.assign({}, Reflect.get(_src_cli_history_tsx__rspack_import_39, 'default'), _src_cli_history_tsx__rspack_import_39); +const route37 = Object.assign({}, Reflect.get(_src_cli_send_tsx__rspack_import_40, 'default'), _src_cli_send_tsx__rspack_import_40); +const route38 = Object.assign({}, Reflect.get(_src_cli_skills_add_tsx__rspack_import_41, 'default'), _src_cli_skills_add_tsx__rspack_import_41); +const route39 = Object.assign({}, Reflect.get(_src_cli_skills_list_tsx__rspack_import_42, 'default'), _src_cli_skills_list_tsx__rspack_import_42); +const route40 = Object.assign({}, Reflect.get(_src_cli_skills_remove_tsx__rspack_import_43, 'default'), _src_cli_skills_remove_tsx__rspack_import_43); +const route41 = Object.assign({}, Reflect.get(_src_cli_thread_tsx__rspack_import_44, 'default'), _src_cli_thread_tsx__rspack_import_44); +const pluginRoot = (0, _agent_bundle_runtime__rspack_import_45.E7)({ fallback: (0, node_url__rspack_import_2.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); @@ -28754,209 +29209,215 @@ const routes = Object.freeze({ name: "bots update", module: route6 }), + "cli:chatgpt-desktop/hosts": Object.freeze({ + id: "cli:chatgpt-desktop/hosts", + kind: "cli", + name: "chatgpt-desktop hosts", + module: route7 + }), "cli:chatgpt-desktop/read": Object.freeze({ id: "cli:chatgpt-desktop/read", kind: "cli", name: "chatgpt-desktop read", - module: route7 + module: route8 }), "cli:chatgpt-desktop/search": Object.freeze({ id: "cli:chatgpt-desktop/search", kind: "cli", name: "chatgpt-desktop search", - module: route8 + module: route9 }), "cli:chatgpt-desktop/send": Object.freeze({ id: "cli:chatgpt-desktop/send", kind: "cli", name: "chatgpt-desktop send", - module: route9 + module: route10 }), "cli:chatgpt-desktop/status": Object.freeze({ id: "cli:chatgpt-desktop/status", kind: "cli", name: "chatgpt-desktop status", - module: route10 + module: route11 }), "cli:chatgpt-desktop/threads": Object.freeze({ id: "cli:chatgpt-desktop/threads", kind: "cli", name: "chatgpt-desktop threads", - module: route11 + module: route12 }), "cli:claude/send": Object.freeze({ id: "cli:claude/send", kind: "cli", name: "claude send", - module: route12 + module: route13 }), "cli:codex/bridge/respond": Object.freeze({ id: "cli:codex/bridge/respond", kind: "cli", name: "codex bridge respond", - module: route13 + module: route14 }), "cli:codex/bridge/run": Object.freeze({ id: "cli:codex/bridge/run", kind: "cli", name: "codex bridge run", - module: route14 + module: route15 }), "cli:codex/bridge/start": Object.freeze({ id: "cli:codex/bridge/start", kind: "cli", name: "codex bridge start", - module: route15 + module: route16 }), "cli:codex/bridge/status": Object.freeze({ id: "cli:codex/bridge/status", kind: "cli", name: "codex bridge status", - module: route16 + module: route17 }), "cli:codex/bridge/stop": Object.freeze({ id: "cli:codex/bridge/stop", kind: "cli", name: "codex bridge stop", - module: route17 + module: route18 }), "cli:codex/desktop-shim": Object.freeze({ id: "cli:codex/desktop-shim", kind: "cli", name: "codex desktop-shim", - module: route18 + module: route19 }), "cli:codex/list-threads": Object.freeze({ id: "cli:codex/list-threads", kind: "cli", name: "codex list-threads", - module: route19 + module: route20 }), "cli:codex/queue": Object.freeze({ id: "cli:codex/queue", kind: "cli", name: "codex queue", - module: route20 + module: route21 }), "cli:codex/send": Object.freeze({ id: "cli:codex/send", kind: "cli", name: "codex send", - module: route21 + module: route22 }), "cli:codex/status": Object.freeze({ id: "cli:codex/status", kind: "cli", name: "codex status", - module: route22 + module: route23 }), "cli:codex/wait": Object.freeze({ id: "cli:codex/wait", kind: "cli", name: "codex wait", - module: route23 + module: route24 }), "cli:codex/watch": Object.freeze({ id: "cli:codex/watch", kind: "cli", name: "codex watch", - module: route24 + module: route25 }), "cli:doctor": Object.freeze({ id: "cli:doctor", kind: "cli", name: "doctor", - module: route25 + module: route26 }), "cli:groups/add": Object.freeze({ id: "cli:groups/add", kind: "cli", name: "groups add", - module: route26 + module: route27 }), "cli:groups/create": Object.freeze({ id: "cli:groups/create", kind: "cli", name: "groups create", - module: route27 + module: route28 }), "cli:groups/delete": Object.freeze({ id: "cli:groups/delete", kind: "cli", name: "groups delete", - module: route28 + module: route29 }), "cli:groups/get": Object.freeze({ id: "cli:groups/get", kind: "cli", name: "groups get", - module: route29 + module: route30 }), "cli:groups/list": Object.freeze({ id: "cli:groups/list", kind: "cli", name: "groups list", - module: route30 + module: route31 }), "cli:groups/members": Object.freeze({ id: "cli:groups/members", kind: "cli", name: "groups members", - module: route31 + module: route32 }), "cli:groups/remove": Object.freeze({ id: "cli:groups/remove", kind: "cli", name: "groups remove", - module: route32 + module: route33 }), "cli:groups/set": Object.freeze({ id: "cli:groups/set", kind: "cli", name: "groups set", - module: route33 + module: route34 }), "cli:groups/update": Object.freeze({ id: "cli:groups/update", kind: "cli", name: "groups update", - module: route34 + module: route35 }), "cli:history": Object.freeze({ id: "cli:history", kind: "cli", name: "history", - module: route35 + module: route36 }), "cli:send": Object.freeze({ id: "cli:send", kind: "cli", name: "send", - module: route36 + module: route37 }), "cli:skills/add": Object.freeze({ id: "cli:skills/add", kind: "cli", name: "skills add", - module: route37 + module: route38 }), "cli:skills/list": Object.freeze({ id: "cli:skills/list", kind: "cli", name: "skills list", - module: route38 + module: route39 }), "cli:skills/remove": Object.freeze({ id: "cli:skills/remove", kind: "cli", name: "skills remove", - module: route39 + module: route40 }), "cli:thread": Object.freeze({ id: "cli:thread", kind: "cli", name: "thread", - module: route40 + module: route41 }) }); const requests = new Map(); @@ -28991,18 +29452,18 @@ const render = async (message)=>{ }; try { const cwd = process.cwd(); - await (0, _agent_bundle_runtime__rspack_import_45.iC)({ + await (0, _agent_bundle_runtime__rspack_import_46.iC)({ capabilities: { - command: (0, _agent_bundle_runtime__rspack_import_45.hU)(), - filesystem: (0, _agent_bundle_runtime__rspack_import_45.hU)(), - network: (0, _agent_bundle_runtime__rspack_import_45.hU)(), - projectRoot: (0, _agent_bundle_runtime__rspack_import_45.qC)({ + command: (0, _agent_bundle_runtime__rspack_import_46.hU)(), + filesystem: (0, _agent_bundle_runtime__rspack_import_46.hU)(), + network: (0, _agent_bundle_runtime__rspack_import_46.hU)(), + projectRoot: (0, _agent_bundle_runtime__rspack_import_46.qC)({ root: cwd }, 'derived') }, - host: (0, _agent_bundle_runtime__rspack_import_45.hU)('unsupported-surface'), + host: (0, _agent_bundle_runtime__rspack_import_46.hU)('unsupported-surface'), invocation: message.request, - lineage: (0, _agent_bundle_runtime__rspack_import_45.hU)('unsupported-surface'), + lineage: (0, _agent_bundle_runtime__rspack_import_46.hU)('unsupported-surface'), plugin: pluginRoot.identity, progress: { report: async (update)=>{ @@ -29015,8 +29476,8 @@ const render = async (message)=>{ }, process: processHit, signal: controller.signal, - terminal: message.terminal === undefined ? (0, _agent_bundle_runtime__rspack_import_45.hU)('not-provided') : (0, _agent_bundle_runtime__rspack_import_45.qC)(message.terminal, 'native'), - workspace: (0, _agent_bundle_runtime__rspack_import_45.qC)({ + terminal: message.terminal === undefined ? (0, _agent_bundle_runtime__rspack_import_46.hU)('not-provided') : (0, _agent_bundle_runtime__rspack_import_46.qC)(message.terminal, 'native'), + workspace: (0, _agent_bundle_runtime__rspack_import_46.qC)({ root: cwd }, 'derived') }, async ()=>{ @@ -29025,7 +29486,7 @@ const render = async (message)=>{ type: 'observed-render-start' }); const renderStartedAt = performance.now(); - const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_46.y)(composeLayouts(observedRoute, { + const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_47.y)(composeLayouts(observedRoute, { ...message.props, signal: controller.signal }, controller.signal), { diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index 28941a4..75dd558 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -7017,6 +7017,52 @@ var __webpack_modules__ = { resultSchema: resultSchema }); }, + "./src/cli/chatgpt-desktop/hosts.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const config = { + description: 'List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.', + exitCode: 'result', + inputJsonSchema: { + additionalProperties: false, + properties: { + port: { + description: 'Local CDP port', + type: 'number' + } + }, + type: 'object' + } + }; + const inputSchema = zod__rspack_import_2.Ikc({ + port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() + }).strict(); + async function chatgptDesktopHosts({ input }) { + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.Bm)(input); + const hosts = Array.isArray(out.hosts) ? out.hosts : []; + const text = hosts.length > 0 ? hosts.map((host)=>{ + const row = host; + const name = row.hostName && row.hostName !== row.hostId ? ` (${row.hostName})` : ''; + return `${row.hostId ?? '?'}${name} [${row.location ?? '?'}] threads=${row.threadCount ?? 0}`; + }).join('\n') + `\n\nhostsSource: ${String(out.hostsSource ?? '')}` + `\nmodelProviders: ${JSON.stringify(out.modelProviders ?? [])}` + `\nmodelProvidersSource: ${String(out.modelProvidersSource ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: text + }) + }); + } + __webpack_require__.d(__webpack_exports__, { + "default": ()=>chatgptDesktopHosts, + resultSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_1.FD + }, { + config: config, + inputSchema: inputSchema + }); + }, "./src/cli/chatgpt-desktop/read.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); @@ -7100,7 +7146,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.', + description: 'Search ChatGPT Desktop threads; --host and --model-provider are separate filters.', exitCode: 'result', positionals: [ 'query' @@ -7108,11 +7154,26 @@ var __webpack_modules__ = { inputJsonSchema: { additionalProperties: false, properties: { + groupBy: { + description: 'Group results by host', + enum: [ + 'host' + ], + type: 'string' + }, + host: { + description: 'Filter: all (default) | local | hostId or friendly name', + type: 'string' + }, limit: { default: 50, description: 'Max matches (1-200)', type: 'number' }, + modelProvider: { + description: 'Pass-through to app-server modelProviders (omit = all)', + type: 'string' + }, port: { description: 'Local CDP port', type: 'number' @@ -7128,7 +7189,10 @@ var __webpack_modules__ = { } }; const inputSchema = zod__rspack_import_2.Ikc({ + groupBy: zod__rspack_import_2.euz('host').optional(), + host: zod__rspack_import_2.YjP().min(1).max(256).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), + modelProvider: zod__rspack_import_2.YjP().min(1).max(256).optional(), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), query: zod__rspack_import_2.YjP().min(1).max(512) }).strict(); @@ -7269,7 +7333,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'List local + remote-control ChatGPT Desktop threads; optional --host and --group-by host.', + description: 'List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, @@ -7282,7 +7346,7 @@ var __webpack_modules__ = { type: 'string' }, host: { - description: 'Filter by hostId or friendly name (local for local-only)', + description: 'Filter: all (default) | local | hostId or friendly name', type: 'string' }, limit: { @@ -7290,6 +7354,10 @@ var __webpack_modules__ = { description: 'Max threads (1-200)', type: 'number' }, + modelProvider: { + description: 'Pass-through to app-server modelProviders (omit = all)', + type: 'string' + }, port: { description: 'Local CDP port', type: 'number' @@ -7302,6 +7370,7 @@ var __webpack_modules__ = { groupBy: zod__rspack_import_2.euz('host').optional(), host: zod__rspack_import_2.YjP().min(1).max(256).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), + modelProvider: zod__rspack_import_2.YjP().min(1).max(256).optional(), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() }).strict(); async function chatgptDesktopThreads({ input }) { @@ -7310,7 +7379,8 @@ var __webpack_modules__ = { const text = threads.length > 0 ? threads.map((thread)=>{ const row = thread; const where = row.location === 'remote' ? ` [remote ${row.hostName || row.hostId || '?'}]` : ' [local]'; - return `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : '') + where; + const provider = row.modelProvider ? ` {${row.modelProvider}}` : ''; + return `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : '') + where + provider; }).join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { value: out, @@ -9611,23 +9681,26 @@ var __webpack_modules__ = { var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _remote_threads_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); - async function appServerListThreads({ limit = 50, cursor } = {}) { + async function appServerListThreads({ limit = 50, cursor, modelProviders = [] } = {}) { const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit, - cursor + cursor, + modelProviders }); return { backend: 'app-server', limit: out.limit, nextCursor: out.nextCursor ?? null, - threads: out.threads.map(mapListedThread) + threads: out.threads.map(mapListedThread), + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } - async function appServerSearchThreads({ query, limit = 50 }) { + async function appServerSearchThreads({ query, limit = 50, modelProviders = [] }) { const needle = query.trim().toLowerCase(); if (!needle) { return appServerListThreads({ - limit + limit, + modelProviders }); } const matched = []; @@ -9635,7 +9708,8 @@ var __webpack_modules__ = { for(let page = 0; page < 20 && matched.length < limit; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit: 200, - cursor + cursor, + modelProviders }); for (const thread of out.threads){ const mapped = mapListedThread(thread); @@ -9650,9 +9724,180 @@ var __webpack_modules__ = { limit, query, nextCursor: null, - threads: matched.slice(0, limit) + threads: matched.slice(0, limit), + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined + }; + } + const MODEL_PROVIDER_LIST_METHODS = [ + 'modelProvider/list', + 'model/providers/list', + 'models/providers/list', + 'account/modelProviders/list', + 'config/modelProviders/list', + 'provider/list' + ]; + const REMOTE_ENVIRONMENT_LIST_METHODS = [ + 'remoteEnvironment/list', + 'remote/environments/list', + 'environment/list', + 'remoteControl/hosts/list', + 'remote/hosts/list', + 'hosts/list' + ]; + async function discoverModelProviders() { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + for (const method of MODEL_PROVIDER_LIST_METHODS){ + try { + const result = await client.request(method, {}); + const providers = normalizeNamedList(result, [ + 'id', + 'name', + 'provider', + 'modelProvider', + 'slug' + ]); + if (providers.length > 0) { + return { + providers, + source: `app-server:${method}` + }; + } + } catch {} + } + } finally{ + client.close(); + } + const providers = new Set(); + let cursor; + for(let page = 0; page < 20; page++){ + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit: 200, + cursor, + modelProviders: [] + }); + for (const thread of out.threads){ + if (typeof thread.modelProvider === 'string' && thread.modelProvider) { + providers.add(thread.modelProvider); + } + } + if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + cursor = out.nextCursor; + } + return { + providers: [ + ...providers + ].sort(), + source: 'thread/list-distinct' + }; + } + async function discoverRemoteEnvironments() { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + for (const method of REMOTE_ENVIRONMENT_LIST_METHODS){ + try { + const result = await client.request(method, {}); + const hosts = normalizeHostEntries(result); + if (hosts.length > 0) { + return { + hosts, + source: `app-server:${method}` + }; + } + } catch {} + } + } finally{ + client.close(); + } + return { + hosts: [], + source: null }; } + function normalizeNamedList(result, idKeys) { + const raw = listPayload(result); + const out = []; + for (const entry of raw){ + if (typeof entry === 'string' && entry) out.push(entry); + else if (entry && typeof entry === 'object') { + const row = entry; + for (const key of idKeys){ + if (typeof row[key] === 'string' && row[key]) { + out.push(String(row[key])); + break; + } + } + } + } + return [ + ...new Set(out) + ].sort(); + } + function normalizeHostEntries(result) { + const raw = listPayload(result); + const out = []; + for (const entry of raw){ + if (typeof entry === 'string' && entry) { + out.push({ + hostId: entry, + hostName: null + }); + continue; + } + if (!entry || typeof entry !== 'object') continue; + const row = entry; + let hostId = null; + for (const key of [ + 'hostId', + 'id', + 'uuid', + 'environmentId', + 'envId' + ]){ + if (typeof row[key] === 'string' && row[key]) { + hostId = String(row[key]); + break; + } + } + if (!hostId) continue; + let hostName = null; + for (const key of [ + 'hostName', + 'name', + 'displayName', + 'envName', + 'label', + 'title' + ]){ + if (typeof row[key] === 'string' && row[key]) { + hostName = String(row[key]); + break; + } + } + out.push({ + hostId, + hostName + }); + } + return out; + } + function listPayload(result) { + if (Array.isArray(result)) return result; + if (!result || typeof result !== 'object') return []; + const record = result; + for (const key of [ + 'data', + 'providers', + 'modelProviders', + 'hosts', + 'environments', + 'remoteEnvironments', + 'items' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + return []; + } async function appServerReadThread({ threadId, limit = 100, full = false }) { const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); @@ -9978,6 +10223,8 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, + OP: ()=>discoverRemoteEnvironments, + X: ()=>discoverModelProviders, aI: ()=>appServerSearchThreads, dM: ()=>appServerStatusProbe }); @@ -10890,7 +11137,10 @@ var __webpack_modules__ = { searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, statusProbe: _app_server_fallback_js__rspack_import_1.dM, - listRemoteThreads: _remote_threads_js__rspack_import_4.Hx + listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, + listHosts: _remote_threads_js__rspack_import_4.Kl, + discoverModelProviders: _app_server_fallback_js__rspack_import_1.X, + discoverRemoteEnvironments: _app_server_fallback_js__rspack_import_1.OP }; class ChatGptDesktopFacade { #cdp; @@ -10920,11 +11170,14 @@ var __webpack_modules__ = { } async listThreads(options = {}) { const limit = options.limit ?? 50; + const host = normalizeHostFilter(options.host); + const modelProviders = modelProvidersFromFilter(options.modelProvider); let appList = null; let appError; try { appList = await this.#fallbacks.listThreads({ - limit + limit, + modelProviders }); } catch (error) { appError = error; @@ -10952,17 +11205,107 @@ var __webpack_modules__ = { else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); return finalizeThreadList(base, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: this.#listRemotes() }); } + async listHosts() { + const remotes = this.#listRemotes(); + let localThreadCount = 0; + try { + const local = await this.#fallbacks.listThreads({ + limit: 200, + modelProviders: [] + }); + localThreadCount = local.threads.length; + } catch { + localThreadCount = 0; + } + const listHosts = this.#fallbacks.listHosts ?? _remote_threads_js__rspack_import_4.Kl; + const fromState = listHosts(process.env, { + localThreadCount + }); + const byId = new Map(fromState.map((host)=>[ + host.hostId, + { + ...host + } + ])); + let hostsSource = 'remote-thread-summaries-v3+local'; + try { + const discoverEnvs = this.#fallbacks.discoverRemoteEnvironments ?? _app_server_fallback_js__rspack_import_1.OP; + const appHosts = await discoverEnvs(); + if (appHosts.source && appHosts.hosts.length > 0) { + for (const host of appHosts.hosts){ + const existing = byId.get(host.hostId); + if (existing) { + byId.set(host.hostId, { + ...existing, + hostName: existing.hostName ?? host.hostName + }); + } else { + byId.set(host.hostId, { + hostId: host.hostId, + hostName: host.hostName, + location: 'remote', + threadCount: 0 + }); + } + } + hostsSource = `${appHosts.source}+remote-thread-summaries-v3+local`; + } + } catch {} + const remoteCounts = new Map(); + for (const thread of remotes){ + remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + } + const withCounts = [ + ...byId.values() + ].map((host)=>host.hostId === 'local' ? { + ...host, + threadCount: localThreadCount + } : { + ...host, + threadCount: remoteCounts.get(host.hostId) ?? host.threadCount + }).sort((a, b)=>{ + if (a.hostId === 'local') return -1; + if (b.hostId === 'local') return 1; + return a.hostId.localeCompare(b.hostId); + }); + let modelProviders = []; + let modelProvidersSource = 'thread/list-distinct'; + try { + const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_1.X; + const discovered = await discover(); + modelProviders = [ + ...discovered.providers + ]; + modelProvidersSource = discovered.source; + } catch { + modelProviders = [ + ...new Set(remotes.map((thread)=>thread.modelProvider).filter((value)=>typeof value === 'string' && Boolean(value))) + ].sort(); + modelProvidersSource = 'remote-summaries-distinct'; + } + return { + hosts: withCounts, + hostsSource, + modelProviders, + modelProvidersSource, + backend: 'app-server' + }; + } async searchThreads(options) { const limit = options.limit ?? 50; + const host = normalizeHostFilter(options.host); + const modelProviders = modelProvidersFromFilter(options.modelProvider); try { const appList = await this.#fallbacks.searchThreads({ query: options.query, - limit + limit, + modelProviders }); const cdpList = await this.#tryCdpList({ limit @@ -10970,7 +11313,8 @@ var __webpack_modules__ = { const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; const withRemotes = finalizeThreadList(base, { limit: 10000, - host: options.host, + host, + modelProvider: options.modelProvider, remotes: this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); @@ -10981,7 +11325,8 @@ var __webpack_modules__ = { }; return finalizeThreadList(filtered, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: [] }); @@ -10998,7 +11343,8 @@ var __webpack_modules__ = { }; return finalizeThreadList(filtered, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: this.#listRemotes() }); @@ -11150,7 +11496,7 @@ var __webpack_modules__ = { threads: merged }; } - function finalizeThreadList(base, { limit, host, groupBy, remotes }) { + function finalizeThreadList(base, { limit, host = 'all', modelProvider, groupBy, remotes }) { const locals = base.threads.map((thread)=>{ const location = thread.location ?? 'local'; return { @@ -11174,7 +11520,11 @@ var __webpack_modules__ = { hostName: remote.hostName ?? null }); } - const filtered = host ? merged.filter((thread)=>hostMatches(thread, host)) : merged; + const filtered = merged.filter((thread)=>{ + if (!hostMatches(thread, host)) return false; + if (!modelProviderMatches(thread, modelProvider)) return false; + return true; + }); const limited = filtered.slice(0, limit); const result = { backend: base.backend, @@ -11186,8 +11536,9 @@ var __webpack_modules__ = { ...base.query !== undefined ? { query: base.query } : {}, - ...host ? { - host + host, + ...modelProvider ? { + modelProvider } : {} }; if (groupBy === 'host') { @@ -11223,15 +11574,32 @@ var __webpack_modules__ = { ...groups.values() ]; } + function normalizeHostFilter(host) { + const value = (host ?? 'all').trim(); + return value || 'all'; + } + function modelProvidersFromFilter(modelProvider) { + if (!modelProvider || !modelProvider.trim()) return []; + return [ + modelProvider.trim() + ]; + } function hostMatches(thread, host) { const needle = host.trim().toLowerCase(); - if (!needle) return true; + if (!needle || needle === 'all') return true; if (needle === 'local') return (thread.location ?? 'local') === 'local'; return [ thread.hostId, thread.hostName ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); } + function modelProviderMatches(thread, modelProvider) { + if (!modelProvider) return true; + if (!thread.modelProvider) { + return thread.location === 'remote'; + } + return thread.modelProvider === modelProvider; + } function threadMatchesQuery(thread, needle) { if (!needle) return true; return [ @@ -11396,6 +11764,57 @@ var __webpack_modules__ = { function findRemoteThreadHostId(threadId, env = process.env) { return findRemoteThread(threadId, env)?.hostId ?? null; } + function listDiscoveredHosts(env = process.env, { localThreadCount = 0 } = {}) { + const remotes = listRemoteThreadsFromState(env); + const byHost = new Map(); + byHost.set('local', { + hostId: 'local', + hostName: 'local', + location: 'local', + threadCount: localThreadCount + }); + const data = loadCodexGlobalState(env); + if (data) { + const hostNames = collectHostNames(data); + for (const key of Object.keys(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match?.[1]) continue; + const hostId = match[1]; + const summary = data[key]; + const hostName = hostNames.get(hostId) ?? extractHostName(summary) ?? null; + byHost.set(hostId, { + hostId, + hostName, + location: 'remote', + threadCount: 0 + }); + } + } + for (const thread of remotes){ + const existing = byHost.get(thread.hostId); + if (existing) { + byHost.set(thread.hostId, { + ...existing, + hostName: existing.hostName ?? thread.hostName, + threadCount: existing.threadCount + 1 + }); + } else { + byHost.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName, + location: 'remote', + threadCount: 1 + }); + } + } + return [ + ...byHost.values() + ].sort((a, b)=>{ + if (a.hostId === 'local') return -1; + if (b.hostId === 'local') return 1; + return a.hostId.localeCompare(b.hostId); + }); + } function collectHostNames(data) { const names = new Map(); for (const [key, value] of Object.entries(data)){ @@ -11684,6 +12103,7 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Hx: ()=>listRemoteThreadsFromState, KI: ()=>findRemoteThread, + Kl: ()=>listDiscoveredHosts, XI: ()=>findRemoteThreadHostId }); }, @@ -11701,6 +12121,7 @@ var __webpack_modules__ = { port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const searchThreadsSchema = zod__rspack_import_4.Ikc({ @@ -11708,8 +12129,12 @@ var __webpack_modules__ = { query: zod__rspack_import_4.YjP().min(1).max(512), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); + const listHostsSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional() + }).strict(); const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, @@ -11798,6 +12223,7 @@ var __webpack_modules__ = { const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ limit: input.limit, host: input.host, + modelProvider: input.modelProvider, groupBy: input.groupBy })); return asResult({ @@ -11818,6 +12244,7 @@ var __webpack_modules__ = { query: input.query, limit: input.limit, host: input.host, + modelProvider: input.modelProvider, groupBy: input.groupBy }); }); @@ -11829,6 +12256,22 @@ var __webpack_modules__ = { return mapError(error); } } + async function listHostsOperation(input) { + try { + const out = await withAdapter(input.port, async (adapter)=>{ + if (typeof adapter.listHosts !== 'function') { + throw new _errors_js__rspack_import_1.EH('listHosts', 'adapter does not implement listHosts'); + } + return adapter.listHosts(); + }); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } async function readThreadOperation(input) { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ @@ -11882,9 +12325,15 @@ var __webpack_modules__ = { return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); + if (Array.isArray(result.hosts)) { + const providers = Array.isArray(result.modelProviders) ? ` providers=${result.modelProviders.length} (${String(result.modelProvidersSource ?? '')})` : ''; + return `${result.hosts.length} hosts via ${String(result.hostsSource ?? result.backend ?? 'unknown')}${providers}`; + } if (Array.isArray(result.threads)) { const via = result.query ? ` matching ${JSON.stringify(result.query)}` : ''; - return `${result.threads.length} threads${via} via ${result.backend ?? 'unknown'}`; + const host = result.host && result.host !== 'all' ? ` host=${result.host}` : ''; + const provider = result.modelProvider ? ` provider=${result.modelProvider}` : ''; + return `${result.threads.length} threads${via}${host}${provider} via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { const mode = result.full ? 'full' : 'page'; @@ -11901,6 +12350,7 @@ var __webpack_modules__ = { return JSON.stringify(result); } __webpack_require__.d(__webpack_exports__, { + Bm: ()=>listHostsOperation, D6: ()=>resultText, UK: ()=>readThreadOperation, UP: ()=>sendOperation, @@ -39602,9 +40052,9 @@ var __webpack_modules__ = { try { var agent_bundle_launch_env_layer__rspack_import_0 = __webpack_require__("./.agent-bundle-virtual/bin-gbot-0.mjs"); var agent_bundle_cli_entry__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/cli-entry.js"); - var _agent_bundle_runtime__rspack_import_45 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); - var _agent_bundle_runtime__rspack_import_46 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); - var _agent_bundle_runtime__rspack_import_47 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/index.js"); + var _agent_bundle_runtime__rspack_import_46 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); + var _agent_bundle_runtime__rspack_import_47 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); + var _agent_bundle_runtime__rspack_import_48 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/index.js"); var node_url__rspack_import_2 = __webpack_require__("node:url"); var node_worker_threads__rspack_import_3 = __webpack_require__("node:worker_threads"); var _src_cli_approvals_list_tsx__rspack_import_4 = __webpack_require__("./src/cli/approvals/list.tsx"); @@ -39614,40 +40064,41 @@ var __webpack_modules__ = { var _src_cli_bots_get_tsx__rspack_import_8 = __webpack_require__("./src/cli/bots/get.tsx"); var _src_cli_bots_list_tsx__rspack_import_9 = __webpack_require__("./src/cli/bots/list.tsx"); var _src_cli_bots_update_tsx__rspack_import_10 = __webpack_require__("./src/cli/bots/update.tsx"); - var _src_cli_chatgpt_desktop_read_tsx__rspack_import_11 = __webpack_require__("./src/cli/chatgpt-desktop/read.tsx"); - var _src_cli_chatgpt_desktop_search_tsx__rspack_import_12 = __webpack_require__("./src/cli/chatgpt-desktop/search.tsx"); - var _src_cli_chatgpt_desktop_send_tsx__rspack_import_13 = __webpack_require__("./src/cli/chatgpt-desktop/send.tsx"); - var _src_cli_chatgpt_desktop_status_tsx__rspack_import_14 = __webpack_require__("./src/cli/chatgpt-desktop/status.tsx"); - var _src_cli_chatgpt_desktop_threads_tsx__rspack_import_15 = __webpack_require__("./src/cli/chatgpt-desktop/threads.tsx"); - var _src_cli_claude_send_tsx__rspack_import_16 = __webpack_require__("./src/cli/claude/send.tsx"); - var _src_cli_codex_bridge_respond_tsx__rspack_import_17 = __webpack_require__("./src/cli/codex/bridge/respond.tsx"); - var _src_cli_codex_bridge_run_tsx__rspack_import_18 = __webpack_require__("./src/cli/codex/bridge/run.tsx"); - var _src_cli_codex_bridge_start_tsx__rspack_import_19 = __webpack_require__("./src/cli/codex/bridge/start.tsx"); - var _src_cli_codex_bridge_status_tsx__rspack_import_20 = __webpack_require__("./src/cli/codex/bridge/status.tsx"); - var _src_cli_codex_bridge_stop_tsx__rspack_import_21 = __webpack_require__("./src/cli/codex/bridge/stop.tsx"); - var _src_cli_codex_desktop_shim_tsx__rspack_import_22 = __webpack_require__("./src/cli/codex/desktop-shim.tsx"); - var _src_cli_codex_list_threads_tsx__rspack_import_23 = __webpack_require__("./src/cli/codex/list-threads.tsx"); - var _src_cli_codex_queue_tsx__rspack_import_24 = __webpack_require__("./src/cli/codex/queue.tsx"); - var _src_cli_codex_send_tsx__rspack_import_25 = __webpack_require__("./src/cli/codex/send.tsx"); - var _src_cli_codex_status_tsx__rspack_import_26 = __webpack_require__("./src/cli/codex/status.tsx"); - var _src_cli_codex_wait_tsx__rspack_import_27 = __webpack_require__("./src/cli/codex/wait.tsx"); - var _src_cli_codex_watch_tsx__rspack_import_28 = __webpack_require__("./src/cli/codex/watch.tsx"); - var _src_cli_doctor_tsx__rspack_import_29 = __webpack_require__("./src/cli/doctor.tsx"); - var _src_cli_groups_add_tsx__rspack_import_30 = __webpack_require__("./src/cli/groups/add.tsx"); - var _src_cli_groups_create_tsx__rspack_import_31 = __webpack_require__("./src/cli/groups/create.tsx"); - var _src_cli_groups_delete_tsx__rspack_import_32 = __webpack_require__("./src/cli/groups/delete.tsx"); - var _src_cli_groups_get_tsx__rspack_import_33 = __webpack_require__("./src/cli/groups/get.tsx"); - var _src_cli_groups_list_tsx__rspack_import_34 = __webpack_require__("./src/cli/groups/list.tsx"); - var _src_cli_groups_members_tsx__rspack_import_35 = __webpack_require__("./src/cli/groups/members.tsx"); - var _src_cli_groups_remove_tsx__rspack_import_36 = __webpack_require__("./src/cli/groups/remove.tsx"); - var _src_cli_groups_set_tsx__rspack_import_37 = __webpack_require__("./src/cli/groups/set.tsx"); - var _src_cli_groups_update_tsx__rspack_import_38 = __webpack_require__("./src/cli/groups/update.tsx"); - var _src_cli_history_tsx__rspack_import_39 = __webpack_require__("./src/cli/history.tsx"); - var _src_cli_send_tsx__rspack_import_40 = __webpack_require__("./src/cli/send.tsx"); - var _src_cli_skills_add_tsx__rspack_import_41 = __webpack_require__("./src/cli/skills/add.tsx"); - var _src_cli_skills_list_tsx__rspack_import_42 = __webpack_require__("./src/cli/skills/list.tsx"); - var _src_cli_skills_remove_tsx__rspack_import_43 = __webpack_require__("./src/cli/skills/remove.tsx"); - var _src_cli_thread_tsx__rspack_import_44 = __webpack_require__("./src/cli/thread.tsx"); + var _src_cli_chatgpt_desktop_hosts_tsx__rspack_import_11 = __webpack_require__("./src/cli/chatgpt-desktop/hosts.tsx"); + var _src_cli_chatgpt_desktop_read_tsx__rspack_import_12 = __webpack_require__("./src/cli/chatgpt-desktop/read.tsx"); + var _src_cli_chatgpt_desktop_search_tsx__rspack_import_13 = __webpack_require__("./src/cli/chatgpt-desktop/search.tsx"); + var _src_cli_chatgpt_desktop_send_tsx__rspack_import_14 = __webpack_require__("./src/cli/chatgpt-desktop/send.tsx"); + var _src_cli_chatgpt_desktop_status_tsx__rspack_import_15 = __webpack_require__("./src/cli/chatgpt-desktop/status.tsx"); + var _src_cli_chatgpt_desktop_threads_tsx__rspack_import_16 = __webpack_require__("./src/cli/chatgpt-desktop/threads.tsx"); + var _src_cli_claude_send_tsx__rspack_import_17 = __webpack_require__("./src/cli/claude/send.tsx"); + var _src_cli_codex_bridge_respond_tsx__rspack_import_18 = __webpack_require__("./src/cli/codex/bridge/respond.tsx"); + var _src_cli_codex_bridge_run_tsx__rspack_import_19 = __webpack_require__("./src/cli/codex/bridge/run.tsx"); + var _src_cli_codex_bridge_start_tsx__rspack_import_20 = __webpack_require__("./src/cli/codex/bridge/start.tsx"); + var _src_cli_codex_bridge_status_tsx__rspack_import_21 = __webpack_require__("./src/cli/codex/bridge/status.tsx"); + var _src_cli_codex_bridge_stop_tsx__rspack_import_22 = __webpack_require__("./src/cli/codex/bridge/stop.tsx"); + var _src_cli_codex_desktop_shim_tsx__rspack_import_23 = __webpack_require__("./src/cli/codex/desktop-shim.tsx"); + var _src_cli_codex_list_threads_tsx__rspack_import_24 = __webpack_require__("./src/cli/codex/list-threads.tsx"); + var _src_cli_codex_queue_tsx__rspack_import_25 = __webpack_require__("./src/cli/codex/queue.tsx"); + var _src_cli_codex_send_tsx__rspack_import_26 = __webpack_require__("./src/cli/codex/send.tsx"); + var _src_cli_codex_status_tsx__rspack_import_27 = __webpack_require__("./src/cli/codex/status.tsx"); + var _src_cli_codex_wait_tsx__rspack_import_28 = __webpack_require__("./src/cli/codex/wait.tsx"); + var _src_cli_codex_watch_tsx__rspack_import_29 = __webpack_require__("./src/cli/codex/watch.tsx"); + var _src_cli_doctor_tsx__rspack_import_30 = __webpack_require__("./src/cli/doctor.tsx"); + var _src_cli_groups_add_tsx__rspack_import_31 = __webpack_require__("./src/cli/groups/add.tsx"); + var _src_cli_groups_create_tsx__rspack_import_32 = __webpack_require__("./src/cli/groups/create.tsx"); + var _src_cli_groups_delete_tsx__rspack_import_33 = __webpack_require__("./src/cli/groups/delete.tsx"); + var _src_cli_groups_get_tsx__rspack_import_34 = __webpack_require__("./src/cli/groups/get.tsx"); + var _src_cli_groups_list_tsx__rspack_import_35 = __webpack_require__("./src/cli/groups/list.tsx"); + var _src_cli_groups_members_tsx__rspack_import_36 = __webpack_require__("./src/cli/groups/members.tsx"); + var _src_cli_groups_remove_tsx__rspack_import_37 = __webpack_require__("./src/cli/groups/remove.tsx"); + var _src_cli_groups_set_tsx__rspack_import_38 = __webpack_require__("./src/cli/groups/set.tsx"); + var _src_cli_groups_update_tsx__rspack_import_39 = __webpack_require__("./src/cli/groups/update.tsx"); + var _src_cli_history_tsx__rspack_import_40 = __webpack_require__("./src/cli/history.tsx"); + var _src_cli_send_tsx__rspack_import_41 = __webpack_require__("./src/cli/send.tsx"); + var _src_cli_skills_add_tsx__rspack_import_42 = __webpack_require__("./src/cli/skills/add.tsx"); + var _src_cli_skills_list_tsx__rspack_import_43 = __webpack_require__("./src/cli/skills/list.tsx"); + var _src_cli_skills_remove_tsx__rspack_import_44 = __webpack_require__("./src/cli/skills/remove.tsx"); + var _src_cli_thread_tsx__rspack_import_45 = __webpack_require__("./src/cli/thread.tsx"); const route0 = Object.assign({}, Reflect.get(_src_cli_approvals_list_tsx__rspack_import_4, 'default'), _src_cli_approvals_list_tsx__rspack_import_4); const route1 = Object.assign({}, Reflect.get(_src_cli_approvals_respond_tsx__rspack_import_5, 'default'), _src_cli_approvals_respond_tsx__rspack_import_5); const route2 = Object.assign({}, Reflect.get(_src_cli_bots_create_tsx__rspack_import_6, 'default'), _src_cli_bots_create_tsx__rspack_import_6); @@ -39655,41 +40106,42 @@ var __webpack_modules__ = { const route4 = Object.assign({}, Reflect.get(_src_cli_bots_get_tsx__rspack_import_8, 'default'), _src_cli_bots_get_tsx__rspack_import_8); const route5 = Object.assign({}, Reflect.get(_src_cli_bots_list_tsx__rspack_import_9, 'default'), _src_cli_bots_list_tsx__rspack_import_9); const route6 = Object.assign({}, Reflect.get(_src_cli_bots_update_tsx__rspack_import_10, 'default'), _src_cli_bots_update_tsx__rspack_import_10); - const route7 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_read_tsx__rspack_import_11, 'default'), _src_cli_chatgpt_desktop_read_tsx__rspack_import_11); - const route8 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_search_tsx__rspack_import_12, 'default'), _src_cli_chatgpt_desktop_search_tsx__rspack_import_12); - const route9 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_send_tsx__rspack_import_13, 'default'), _src_cli_chatgpt_desktop_send_tsx__rspack_import_13); - const route10 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_status_tsx__rspack_import_14, 'default'), _src_cli_chatgpt_desktop_status_tsx__rspack_import_14); - const route11 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_threads_tsx__rspack_import_15, 'default'), _src_cli_chatgpt_desktop_threads_tsx__rspack_import_15); - const route12 = Object.assign({}, Reflect.get(_src_cli_claude_send_tsx__rspack_import_16, 'default'), _src_cli_claude_send_tsx__rspack_import_16); - const route13 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_respond_tsx__rspack_import_17, 'default'), _src_cli_codex_bridge_respond_tsx__rspack_import_17); - const route14 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_run_tsx__rspack_import_18, 'default'), _src_cli_codex_bridge_run_tsx__rspack_import_18); - const route15 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_start_tsx__rspack_import_19, 'default'), _src_cli_codex_bridge_start_tsx__rspack_import_19); - const route16 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_status_tsx__rspack_import_20, 'default'), _src_cli_codex_bridge_status_tsx__rspack_import_20); - const route17 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_stop_tsx__rspack_import_21, 'default'), _src_cli_codex_bridge_stop_tsx__rspack_import_21); - const route18 = Object.assign({}, Reflect.get(_src_cli_codex_desktop_shim_tsx__rspack_import_22, 'default'), _src_cli_codex_desktop_shim_tsx__rspack_import_22); - const route19 = Object.assign({}, Reflect.get(_src_cli_codex_list_threads_tsx__rspack_import_23, 'default'), _src_cli_codex_list_threads_tsx__rspack_import_23); - const route20 = Object.assign({}, Reflect.get(_src_cli_codex_queue_tsx__rspack_import_24, 'default'), _src_cli_codex_queue_tsx__rspack_import_24); - const route21 = Object.assign({}, Reflect.get(_src_cli_codex_send_tsx__rspack_import_25, 'default'), _src_cli_codex_send_tsx__rspack_import_25); - const route22 = Object.assign({}, Reflect.get(_src_cli_codex_status_tsx__rspack_import_26, 'default'), _src_cli_codex_status_tsx__rspack_import_26); - const route23 = Object.assign({}, Reflect.get(_src_cli_codex_wait_tsx__rspack_import_27, 'default'), _src_cli_codex_wait_tsx__rspack_import_27); - const route24 = Object.assign({}, Reflect.get(_src_cli_codex_watch_tsx__rspack_import_28, 'default'), _src_cli_codex_watch_tsx__rspack_import_28); - const route25 = Object.assign({}, Reflect.get(_src_cli_doctor_tsx__rspack_import_29, 'default'), _src_cli_doctor_tsx__rspack_import_29); - const route26 = Object.assign({}, Reflect.get(_src_cli_groups_add_tsx__rspack_import_30, 'default'), _src_cli_groups_add_tsx__rspack_import_30); - const route27 = Object.assign({}, Reflect.get(_src_cli_groups_create_tsx__rspack_import_31, 'default'), _src_cli_groups_create_tsx__rspack_import_31); - const route28 = Object.assign({}, Reflect.get(_src_cli_groups_delete_tsx__rspack_import_32, 'default'), _src_cli_groups_delete_tsx__rspack_import_32); - const route29 = Object.assign({}, Reflect.get(_src_cli_groups_get_tsx__rspack_import_33, 'default'), _src_cli_groups_get_tsx__rspack_import_33); - const route30 = Object.assign({}, Reflect.get(_src_cli_groups_list_tsx__rspack_import_34, 'default'), _src_cli_groups_list_tsx__rspack_import_34); - const route31 = Object.assign({}, Reflect.get(_src_cli_groups_members_tsx__rspack_import_35, 'default'), _src_cli_groups_members_tsx__rspack_import_35); - const route32 = Object.assign({}, Reflect.get(_src_cli_groups_remove_tsx__rspack_import_36, 'default'), _src_cli_groups_remove_tsx__rspack_import_36); - const route33 = Object.assign({}, Reflect.get(_src_cli_groups_set_tsx__rspack_import_37, 'default'), _src_cli_groups_set_tsx__rspack_import_37); - const route34 = Object.assign({}, Reflect.get(_src_cli_groups_update_tsx__rspack_import_38, 'default'), _src_cli_groups_update_tsx__rspack_import_38); - const route35 = Object.assign({}, Reflect.get(_src_cli_history_tsx__rspack_import_39, 'default'), _src_cli_history_tsx__rspack_import_39); - const route36 = Object.assign({}, Reflect.get(_src_cli_send_tsx__rspack_import_40, 'default'), _src_cli_send_tsx__rspack_import_40); - const route37 = Object.assign({}, Reflect.get(_src_cli_skills_add_tsx__rspack_import_41, 'default'), _src_cli_skills_add_tsx__rspack_import_41); - const route38 = Object.assign({}, Reflect.get(_src_cli_skills_list_tsx__rspack_import_42, 'default'), _src_cli_skills_list_tsx__rspack_import_42); - const route39 = Object.assign({}, Reflect.get(_src_cli_skills_remove_tsx__rspack_import_43, 'default'), _src_cli_skills_remove_tsx__rspack_import_43); - const route40 = Object.assign({}, Reflect.get(_src_cli_thread_tsx__rspack_import_44, 'default'), _src_cli_thread_tsx__rspack_import_44); - const pluginRoot = (0, _agent_bundle_runtime__rspack_import_45.E7)({ + const route7 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_hosts_tsx__rspack_import_11, 'default'), _src_cli_chatgpt_desktop_hosts_tsx__rspack_import_11); + const route8 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_read_tsx__rspack_import_12, 'default'), _src_cli_chatgpt_desktop_read_tsx__rspack_import_12); + const route9 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_search_tsx__rspack_import_13, 'default'), _src_cli_chatgpt_desktop_search_tsx__rspack_import_13); + const route10 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_send_tsx__rspack_import_14, 'default'), _src_cli_chatgpt_desktop_send_tsx__rspack_import_14); + const route11 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_status_tsx__rspack_import_15, 'default'), _src_cli_chatgpt_desktop_status_tsx__rspack_import_15); + const route12 = Object.assign({}, Reflect.get(_src_cli_chatgpt_desktop_threads_tsx__rspack_import_16, 'default'), _src_cli_chatgpt_desktop_threads_tsx__rspack_import_16); + const route13 = Object.assign({}, Reflect.get(_src_cli_claude_send_tsx__rspack_import_17, 'default'), _src_cli_claude_send_tsx__rspack_import_17); + const route14 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_respond_tsx__rspack_import_18, 'default'), _src_cli_codex_bridge_respond_tsx__rspack_import_18); + const route15 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_run_tsx__rspack_import_19, 'default'), _src_cli_codex_bridge_run_tsx__rspack_import_19); + const route16 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_start_tsx__rspack_import_20, 'default'), _src_cli_codex_bridge_start_tsx__rspack_import_20); + const route17 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_status_tsx__rspack_import_21, 'default'), _src_cli_codex_bridge_status_tsx__rspack_import_21); + const route18 = Object.assign({}, Reflect.get(_src_cli_codex_bridge_stop_tsx__rspack_import_22, 'default'), _src_cli_codex_bridge_stop_tsx__rspack_import_22); + const route19 = Object.assign({}, Reflect.get(_src_cli_codex_desktop_shim_tsx__rspack_import_23, 'default'), _src_cli_codex_desktop_shim_tsx__rspack_import_23); + const route20 = Object.assign({}, Reflect.get(_src_cli_codex_list_threads_tsx__rspack_import_24, 'default'), _src_cli_codex_list_threads_tsx__rspack_import_24); + const route21 = Object.assign({}, Reflect.get(_src_cli_codex_queue_tsx__rspack_import_25, 'default'), _src_cli_codex_queue_tsx__rspack_import_25); + const route22 = Object.assign({}, Reflect.get(_src_cli_codex_send_tsx__rspack_import_26, 'default'), _src_cli_codex_send_tsx__rspack_import_26); + const route23 = Object.assign({}, Reflect.get(_src_cli_codex_status_tsx__rspack_import_27, 'default'), _src_cli_codex_status_tsx__rspack_import_27); + const route24 = Object.assign({}, Reflect.get(_src_cli_codex_wait_tsx__rspack_import_28, 'default'), _src_cli_codex_wait_tsx__rspack_import_28); + const route25 = Object.assign({}, Reflect.get(_src_cli_codex_watch_tsx__rspack_import_29, 'default'), _src_cli_codex_watch_tsx__rspack_import_29); + const route26 = Object.assign({}, Reflect.get(_src_cli_doctor_tsx__rspack_import_30, 'default'), _src_cli_doctor_tsx__rspack_import_30); + const route27 = Object.assign({}, Reflect.get(_src_cli_groups_add_tsx__rspack_import_31, 'default'), _src_cli_groups_add_tsx__rspack_import_31); + const route28 = Object.assign({}, Reflect.get(_src_cli_groups_create_tsx__rspack_import_32, 'default'), _src_cli_groups_create_tsx__rspack_import_32); + const route29 = Object.assign({}, Reflect.get(_src_cli_groups_delete_tsx__rspack_import_33, 'default'), _src_cli_groups_delete_tsx__rspack_import_33); + const route30 = Object.assign({}, Reflect.get(_src_cli_groups_get_tsx__rspack_import_34, 'default'), _src_cli_groups_get_tsx__rspack_import_34); + const route31 = Object.assign({}, Reflect.get(_src_cli_groups_list_tsx__rspack_import_35, 'default'), _src_cli_groups_list_tsx__rspack_import_35); + const route32 = Object.assign({}, Reflect.get(_src_cli_groups_members_tsx__rspack_import_36, 'default'), _src_cli_groups_members_tsx__rspack_import_36); + const route33 = Object.assign({}, Reflect.get(_src_cli_groups_remove_tsx__rspack_import_37, 'default'), _src_cli_groups_remove_tsx__rspack_import_37); + const route34 = Object.assign({}, Reflect.get(_src_cli_groups_set_tsx__rspack_import_38, 'default'), _src_cli_groups_set_tsx__rspack_import_38); + const route35 = Object.assign({}, Reflect.get(_src_cli_groups_update_tsx__rspack_import_39, 'default'), _src_cli_groups_update_tsx__rspack_import_39); + const route36 = Object.assign({}, Reflect.get(_src_cli_history_tsx__rspack_import_40, 'default'), _src_cli_history_tsx__rspack_import_40); + const route37 = Object.assign({}, Reflect.get(_src_cli_send_tsx__rspack_import_41, 'default'), _src_cli_send_tsx__rspack_import_41); + const route38 = Object.assign({}, Reflect.get(_src_cli_skills_add_tsx__rspack_import_42, 'default'), _src_cli_skills_add_tsx__rspack_import_42); + const route39 = Object.assign({}, Reflect.get(_src_cli_skills_list_tsx__rspack_import_43, 'default'), _src_cli_skills_list_tsx__rspack_import_43); + const route40 = Object.assign({}, Reflect.get(_src_cli_skills_remove_tsx__rspack_import_44, 'default'), _src_cli_skills_remove_tsx__rspack_import_44); + const route41 = Object.assign({}, Reflect.get(_src_cli_thread_tsx__rspack_import_45, 'default'), _src_cli_thread_tsx__rspack_import_45); + const pluginRoot = (0, _agent_bundle_runtime__rspack_import_46.E7)({ fallback: (0, node_url__rspack_import_2.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); @@ -39720,107 +40172,110 @@ var __webpack_modules__ = { "cli:bots/update": Object.freeze({ module: route6 }), - "cli:chatgpt-desktop/read": Object.freeze({ + "cli:chatgpt-desktop/hosts": Object.freeze({ module: route7 }), - "cli:chatgpt-desktop/search": Object.freeze({ + "cli:chatgpt-desktop/read": Object.freeze({ module: route8 }), - "cli:chatgpt-desktop/send": Object.freeze({ + "cli:chatgpt-desktop/search": Object.freeze({ module: route9 }), - "cli:chatgpt-desktop/status": Object.freeze({ + "cli:chatgpt-desktop/send": Object.freeze({ module: route10 }), - "cli:chatgpt-desktop/threads": Object.freeze({ + "cli:chatgpt-desktop/status": Object.freeze({ module: route11 }), - "cli:claude/send": Object.freeze({ + "cli:chatgpt-desktop/threads": Object.freeze({ module: route12 }), - "cli:codex/bridge/respond": Object.freeze({ + "cli:claude/send": Object.freeze({ module: route13 }), - "cli:codex/bridge/run": Object.freeze({ + "cli:codex/bridge/respond": Object.freeze({ module: route14 }), - "cli:codex/bridge/start": Object.freeze({ + "cli:codex/bridge/run": Object.freeze({ module: route15 }), - "cli:codex/bridge/status": Object.freeze({ + "cli:codex/bridge/start": Object.freeze({ module: route16 }), - "cli:codex/bridge/stop": Object.freeze({ + "cli:codex/bridge/status": Object.freeze({ module: route17 }), - "cli:codex/desktop-shim": Object.freeze({ + "cli:codex/bridge/stop": Object.freeze({ module: route18 }), - "cli:codex/list-threads": Object.freeze({ + "cli:codex/desktop-shim": Object.freeze({ module: route19 }), - "cli:codex/queue": Object.freeze({ + "cli:codex/list-threads": Object.freeze({ module: route20 }), - "cli:codex/send": Object.freeze({ + "cli:codex/queue": Object.freeze({ module: route21 }), - "cli:codex/status": Object.freeze({ + "cli:codex/send": Object.freeze({ module: route22 }), - "cli:codex/wait": Object.freeze({ + "cli:codex/status": Object.freeze({ module: route23 }), - "cli:codex/watch": Object.freeze({ + "cli:codex/wait": Object.freeze({ module: route24 }), - "cli:doctor": Object.freeze({ + "cli:codex/watch": Object.freeze({ module: route25 }), - "cli:groups/add": Object.freeze({ + "cli:doctor": Object.freeze({ module: route26 }), - "cli:groups/create": Object.freeze({ + "cli:groups/add": Object.freeze({ module: route27 }), - "cli:groups/delete": Object.freeze({ + "cli:groups/create": Object.freeze({ module: route28 }), - "cli:groups/get": Object.freeze({ + "cli:groups/delete": Object.freeze({ module: route29 }), - "cli:groups/list": Object.freeze({ + "cli:groups/get": Object.freeze({ module: route30 }), - "cli:groups/members": Object.freeze({ + "cli:groups/list": Object.freeze({ module: route31 }), - "cli:groups/remove": Object.freeze({ + "cli:groups/members": Object.freeze({ module: route32 }), - "cli:groups/set": Object.freeze({ + "cli:groups/remove": Object.freeze({ module: route33 }), - "cli:groups/update": Object.freeze({ + "cli:groups/set": Object.freeze({ module: route34 }), - "cli:history": Object.freeze({ + "cli:groups/update": Object.freeze({ module: route35 }), - "cli:send": Object.freeze({ + "cli:history": Object.freeze({ module: route36 }), - "cli:skills/add": Object.freeze({ + "cli:send": Object.freeze({ module: route37 }), - "cli:skills/list": Object.freeze({ + "cli:skills/add": Object.freeze({ module: route38 }), - "cli:skills/remove": Object.freeze({ + "cli:skills/list": Object.freeze({ module: route39 }), - "cli:thread": Object.freeze({ + "cli:skills/remove": Object.freeze({ module: route40 + }), + "cli:thread": Object.freeze({ + module: route41 }) }); const commands = Object.freeze([ @@ -40186,6 +40641,27 @@ var __webpack_modules__ = { "rendered": true, "routeId": "cli:bots/update" }, + { + "aliases": [], + "description": "List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.", + "exitCode": "result", + "options": [ + { + "description": "Local CDP port", + "key": "port", + "kind": "number", + "option": "port", + "repeated": false, + "required": false + } + ], + "path": [ + "chatgpt-desktop", + "hosts" + ], + "rendered": true, + "routeId": "cli:chatgpt-desktop/hosts" + }, { "aliases": [], "description": "Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.", @@ -40243,9 +40719,28 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "Search ChatGPT Desktop threads via app-server (full provider list); merge CDP selected/pinned.", + "description": "Search ChatGPT Desktop threads; --host and --model-provider are separate filters.", "exitCode": "result", "options": [ + { + "choices": [ + "host" + ], + "description": "Group results by host", + "key": "groupBy", + "kind": "enum", + "option": "group-by", + "repeated": false, + "required": false + }, + { + "description": "Filter: all (default) | local | hostId or friendly name", + "key": "host", + "kind": "string", + "option": "host", + "repeated": false, + "required": false + }, { "defaultValue": 50, "description": "Max matches (1-200)", @@ -40255,6 +40750,14 @@ var __webpack_modules__ = { "repeated": false, "required": false }, + { + "description": "Pass-through to app-server modelProviders (omit = all)", + "key": "modelProvider", + "kind": "string", + "option": "model-provider", + "repeated": false, + "required": false + }, { "description": "Local CDP port", "key": "port", @@ -40354,7 +40857,7 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "List local + remote-control ChatGPT Desktop threads; optional --host and --group-by host.", + "description": "List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.", "exitCode": "result", "options": [ { @@ -40369,7 +40872,7 @@ var __webpack_modules__ = { "required": false }, { - "description": "Filter by hostId or friendly name (local for local-only)", + "description": "Filter: all (default) | local | hostId or friendly name", "key": "host", "kind": "string", "option": "host", @@ -40385,6 +40888,14 @@ var __webpack_modules__ = { "repeated": false, "required": false }, + { + "description": "Pass-through to app-server modelProviders (omit = all)", + "key": "modelProvider", + "kind": "string", + "option": "model-provider", + "repeated": false, + "required": false + }, { "description": "Local CDP port", "key": "port", @@ -41983,27 +42494,27 @@ var __webpack_modules__ = { instanceId: processLifetime.instanceId, pid: processLifetime.pid }; - const result = await (0, _agent_bundle_runtime__rspack_import_46.iC)({ + const result = await (0, _agent_bundle_runtime__rspack_import_47.iC)({ capabilities: { - command: (0, _agent_bundle_runtime__rspack_import_46.hU)(), - filesystem: (0, _agent_bundle_runtime__rspack_import_46.hU)(), - network: (0, _agent_bundle_runtime__rspack_import_46.hU)(), - projectRoot: (0, _agent_bundle_runtime__rspack_import_46.qC)({ + command: (0, _agent_bundle_runtime__rspack_import_47.hU)(), + filesystem: (0, _agent_bundle_runtime__rspack_import_47.hU)(), + network: (0, _agent_bundle_runtime__rspack_import_47.hU)(), + projectRoot: (0, _agent_bundle_runtime__rspack_import_47.qC)({ root: cwd }, 'derived') }, - host: (0, _agent_bundle_runtime__rspack_import_46.hU)('unsupported-surface'), + host: (0, _agent_bundle_runtime__rspack_import_47.hU)('unsupported-surface'), invocation: { kind: 'cli', operationId: command.routeId, surface: command.path.join(' ') }, - lineage: (0, _agent_bundle_runtime__rspack_import_46.hU)('unsupported-surface'), + lineage: (0, _agent_bundle_runtime__rspack_import_47.hU)('unsupported-surface'), plugin: pluginRoot.identity, process: processHit, signal: context.signal, - terminal: (0, _agent_bundle_runtime__rspack_import_46.qC)(context.terminal, 'native'), - workspace: (0, _agent_bundle_runtime__rspack_import_46.qC)({ + terminal: (0, _agent_bundle_runtime__rspack_import_47.qC)(context.terminal, 'native'), + workspace: (0, _agent_bundle_runtime__rspack_import_47.qC)({ root: cwd }, 'derived') }, async ()=>route.module.default({ @@ -42110,7 +42621,7 @@ var __webpack_modules__ = { return stream; } }); - const dispatcher = (0, _agent_bundle_runtime__rspack_import_47.jK)(host); + const dispatcher = (0, _agent_bundle_runtime__rspack_import_48.jK)(host); return Object.freeze({ close: async ()=>{ await worker.terminate(); @@ -43466,17 +43977,20 @@ var __webpack_modules__ = { }; } const THREAD_LIST_MAX_LIMIT = 200; - async function listCodexThreads1({ limit = 20, cursor, env = process.env } = {}) { + async function listCodexThreads1({ limit = 20, cursor, modelProviders = [], env = process.env } = {}) { if (!Number.isInteger(limit) || limit < 1 || limit > THREAD_LIST_MAX_LIMIT) { throw new RangeError("--limit must be an integer 1-" + THREAD_LIST_MAX_LIMIT); } if (cursor !== undefined && (typeof cursor !== "string" || !cursor)) throw new RangeError("--cursor must be a non-empty string"); + if (!Array.isArray(modelProviders) || modelProviders.some((p)=>typeof p !== "string")) { + throw new RangeError("modelProviders must be an array of strings (empty = all providers)"); + } const { client } = await openSession(env); try { const params = { limit, useStateDbOnly: true, - modelProviders: [], + modelProviders, ...cursor !== undefined ? { cursor } : {} diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index 7af5ca2..9b3a4fd 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8089,23 +8089,26 @@ var __webpack_modules__ = { var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _remote_threads_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); - async function appServerListThreads({ limit = 50, cursor } = {}) { + async function appServerListThreads({ limit = 50, cursor, modelProviders = [] } = {}) { const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit, - cursor + cursor, + modelProviders }); return { backend: 'app-server', limit: out.limit, nextCursor: out.nextCursor ?? null, - threads: out.threads.map(mapListedThread) + threads: out.threads.map(mapListedThread), + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } - async function appServerSearchThreads({ query, limit = 50 }) { + async function appServerSearchThreads({ query, limit = 50, modelProviders = [] }) { const needle = query.trim().toLowerCase(); if (!needle) { return appServerListThreads({ - limit + limit, + modelProviders }); } const matched = []; @@ -8113,7 +8116,8 @@ var __webpack_modules__ = { for(let page = 0; page < 20 && matched.length < limit; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit: 200, - cursor + cursor, + modelProviders }); for (const thread of out.threads){ const mapped = mapListedThread(thread); @@ -8128,9 +8132,180 @@ var __webpack_modules__ = { limit, query, nextCursor: null, - threads: matched.slice(0, limit) + threads: matched.slice(0, limit), + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } + const MODEL_PROVIDER_LIST_METHODS = [ + 'modelProvider/list', + 'model/providers/list', + 'models/providers/list', + 'account/modelProviders/list', + 'config/modelProviders/list', + 'provider/list' + ]; + const REMOTE_ENVIRONMENT_LIST_METHODS = [ + 'remoteEnvironment/list', + 'remote/environments/list', + 'environment/list', + 'remoteControl/hosts/list', + 'remote/hosts/list', + 'hosts/list' + ]; + async function discoverModelProviders() { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + for (const method of MODEL_PROVIDER_LIST_METHODS){ + try { + const result = await client.request(method, {}); + const providers = normalizeNamedList(result, [ + 'id', + 'name', + 'provider', + 'modelProvider', + 'slug' + ]); + if (providers.length > 0) { + return { + providers, + source: `app-server:${method}` + }; + } + } catch {} + } + } finally{ + client.close(); + } + const providers = new Set(); + let cursor; + for(let page = 0; page < 20; page++){ + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit: 200, + cursor, + modelProviders: [] + }); + for (const thread of out.threads){ + if (typeof thread.modelProvider === 'string' && thread.modelProvider) { + providers.add(thread.modelProvider); + } + } + if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + cursor = out.nextCursor; + } + return { + providers: [ + ...providers + ].sort(), + source: 'thread/list-distinct' + }; + } + async function discoverRemoteEnvironments() { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + for (const method of REMOTE_ENVIRONMENT_LIST_METHODS){ + try { + const result = await client.request(method, {}); + const hosts = normalizeHostEntries(result); + if (hosts.length > 0) { + return { + hosts, + source: `app-server:${method}` + }; + } + } catch {} + } + } finally{ + client.close(); + } + return { + hosts: [], + source: null + }; + } + function normalizeNamedList(result, idKeys) { + const raw = listPayload(result); + const out = []; + for (const entry of raw){ + if (typeof entry === 'string' && entry) out.push(entry); + else if (entry && typeof entry === 'object') { + const row = entry; + for (const key of idKeys){ + if (typeof row[key] === 'string' && row[key]) { + out.push(String(row[key])); + break; + } + } + } + } + return [ + ...new Set(out) + ].sort(); + } + function normalizeHostEntries(result) { + const raw = listPayload(result); + const out = []; + for (const entry of raw){ + if (typeof entry === 'string' && entry) { + out.push({ + hostId: entry, + hostName: null + }); + continue; + } + if (!entry || typeof entry !== 'object') continue; + const row = entry; + let hostId = null; + for (const key of [ + 'hostId', + 'id', + 'uuid', + 'environmentId', + 'envId' + ]){ + if (typeof row[key] === 'string' && row[key]) { + hostId = String(row[key]); + break; + } + } + if (!hostId) continue; + let hostName = null; + for (const key of [ + 'hostName', + 'name', + 'displayName', + 'envName', + 'label', + 'title' + ]){ + if (typeof row[key] === 'string' && row[key]) { + hostName = String(row[key]); + break; + } + } + out.push({ + hostId, + hostName + }); + } + return out; + } + function listPayload(result) { + if (Array.isArray(result)) return result; + if (!result || typeof result !== 'object') return []; + const record = result; + for (const key of [ + 'data', + 'providers', + 'modelProviders', + 'hosts', + 'environments', + 'remoteEnvironments', + 'items' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + return []; + } async function appServerReadThread({ threadId, limit = 100, full = false }) { const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); @@ -8456,6 +8631,8 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, + OP: ()=>discoverRemoteEnvironments, + X: ()=>discoverModelProviders, aI: ()=>appServerSearchThreads, dM: ()=>appServerStatusProbe }); @@ -9368,7 +9545,10 @@ var __webpack_modules__ = { searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, statusProbe: _app_server_fallback_js__rspack_import_1.dM, - listRemoteThreads: _remote_threads_js__rspack_import_4.Hx + listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, + listHosts: _remote_threads_js__rspack_import_4.Kl, + discoverModelProviders: _app_server_fallback_js__rspack_import_1.X, + discoverRemoteEnvironments: _app_server_fallback_js__rspack_import_1.OP }; class ChatGptDesktopFacade { #cdp; @@ -9398,11 +9578,14 @@ var __webpack_modules__ = { } async listThreads(options = {}) { const limit = options.limit ?? 50; + const host = normalizeHostFilter(options.host); + const modelProviders = modelProvidersFromFilter(options.modelProvider); let appList = null; let appError; try { appList = await this.#fallbacks.listThreads({ - limit + limit, + modelProviders }); } catch (error) { appError = error; @@ -9430,17 +9613,107 @@ var __webpack_modules__ = { else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); return finalizeThreadList(base, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: this.#listRemotes() }); } + async listHosts() { + const remotes = this.#listRemotes(); + let localThreadCount = 0; + try { + const local = await this.#fallbacks.listThreads({ + limit: 200, + modelProviders: [] + }); + localThreadCount = local.threads.length; + } catch { + localThreadCount = 0; + } + const listHosts = this.#fallbacks.listHosts ?? _remote_threads_js__rspack_import_4.Kl; + const fromState = listHosts(process.env, { + localThreadCount + }); + const byId = new Map(fromState.map((host)=>[ + host.hostId, + { + ...host + } + ])); + let hostsSource = 'remote-thread-summaries-v3+local'; + try { + const discoverEnvs = this.#fallbacks.discoverRemoteEnvironments ?? _app_server_fallback_js__rspack_import_1.OP; + const appHosts = await discoverEnvs(); + if (appHosts.source && appHosts.hosts.length > 0) { + for (const host of appHosts.hosts){ + const existing = byId.get(host.hostId); + if (existing) { + byId.set(host.hostId, { + ...existing, + hostName: existing.hostName ?? host.hostName + }); + } else { + byId.set(host.hostId, { + hostId: host.hostId, + hostName: host.hostName, + location: 'remote', + threadCount: 0 + }); + } + } + hostsSource = `${appHosts.source}+remote-thread-summaries-v3+local`; + } + } catch {} + const remoteCounts = new Map(); + for (const thread of remotes){ + remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + } + const withCounts = [ + ...byId.values() + ].map((host)=>host.hostId === 'local' ? { + ...host, + threadCount: localThreadCount + } : { + ...host, + threadCount: remoteCounts.get(host.hostId) ?? host.threadCount + }).sort((a, b)=>{ + if (a.hostId === 'local') return -1; + if (b.hostId === 'local') return 1; + return a.hostId.localeCompare(b.hostId); + }); + let modelProviders = []; + let modelProvidersSource = 'thread/list-distinct'; + try { + const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_1.X; + const discovered = await discover(); + modelProviders = [ + ...discovered.providers + ]; + modelProvidersSource = discovered.source; + } catch { + modelProviders = [ + ...new Set(remotes.map((thread)=>thread.modelProvider).filter((value)=>typeof value === 'string' && Boolean(value))) + ].sort(); + modelProvidersSource = 'remote-summaries-distinct'; + } + return { + hosts: withCounts, + hostsSource, + modelProviders, + modelProvidersSource, + backend: 'app-server' + }; + } async searchThreads(options) { const limit = options.limit ?? 50; + const host = normalizeHostFilter(options.host); + const modelProviders = modelProvidersFromFilter(options.modelProvider); try { const appList = await this.#fallbacks.searchThreads({ query: options.query, - limit + limit, + modelProviders }); const cdpList = await this.#tryCdpList({ limit @@ -9448,7 +9721,8 @@ var __webpack_modules__ = { const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; const withRemotes = finalizeThreadList(base, { limit: 10000, - host: options.host, + host, + modelProvider: options.modelProvider, remotes: this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); @@ -9459,7 +9733,8 @@ var __webpack_modules__ = { }; return finalizeThreadList(filtered, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: [] }); @@ -9476,7 +9751,8 @@ var __webpack_modules__ = { }; return finalizeThreadList(filtered, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: this.#listRemotes() }); @@ -9628,7 +9904,7 @@ var __webpack_modules__ = { threads: merged }; } - function finalizeThreadList(base, { limit, host, groupBy, remotes }) { + function finalizeThreadList(base, { limit, host = 'all', modelProvider, groupBy, remotes }) { const locals = base.threads.map((thread)=>{ const location = thread.location ?? 'local'; return { @@ -9652,7 +9928,11 @@ var __webpack_modules__ = { hostName: remote.hostName ?? null }); } - const filtered = host ? merged.filter((thread)=>hostMatches(thread, host)) : merged; + const filtered = merged.filter((thread)=>{ + if (!hostMatches(thread, host)) return false; + if (!modelProviderMatches(thread, modelProvider)) return false; + return true; + }); const limited = filtered.slice(0, limit); const result = { backend: base.backend, @@ -9664,8 +9944,9 @@ var __webpack_modules__ = { ...base.query !== undefined ? { query: base.query } : {}, - ...host ? { - host + host, + ...modelProvider ? { + modelProvider } : {} }; if (groupBy === 'host') { @@ -9701,15 +9982,32 @@ var __webpack_modules__ = { ...groups.values() ]; } + function normalizeHostFilter(host) { + const value = (host ?? 'all').trim(); + return value || 'all'; + } + function modelProvidersFromFilter(modelProvider) { + if (!modelProvider || !modelProvider.trim()) return []; + return [ + modelProvider.trim() + ]; + } function hostMatches(thread, host) { const needle = host.trim().toLowerCase(); - if (!needle) return true; + if (!needle || needle === 'all') return true; if (needle === 'local') return (thread.location ?? 'local') === 'local'; return [ thread.hostId, thread.hostName ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); } + function modelProviderMatches(thread, modelProvider) { + if (!modelProvider) return true; + if (!thread.modelProvider) { + return thread.location === 'remote'; + } + return thread.modelProvider === modelProvider; + } function threadMatchesQuery(thread, needle) { if (!needle) return true; return [ @@ -9874,6 +10172,57 @@ var __webpack_modules__ = { function findRemoteThreadHostId(threadId, env = process.env) { return findRemoteThread(threadId, env)?.hostId ?? null; } + function listDiscoveredHosts(env = process.env, { localThreadCount = 0 } = {}) { + const remotes = listRemoteThreadsFromState(env); + const byHost = new Map(); + byHost.set('local', { + hostId: 'local', + hostName: 'local', + location: 'local', + threadCount: localThreadCount + }); + const data = loadCodexGlobalState(env); + if (data) { + const hostNames = collectHostNames(data); + for (const key of Object.keys(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match?.[1]) continue; + const hostId = match[1]; + const summary = data[key]; + const hostName = hostNames.get(hostId) ?? extractHostName(summary) ?? null; + byHost.set(hostId, { + hostId, + hostName, + location: 'remote', + threadCount: 0 + }); + } + } + for (const thread of remotes){ + const existing = byHost.get(thread.hostId); + if (existing) { + byHost.set(thread.hostId, { + ...existing, + hostName: existing.hostName ?? thread.hostName, + threadCount: existing.threadCount + 1 + }); + } else { + byHost.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName, + location: 'remote', + threadCount: 1 + }); + } + } + return [ + ...byHost.values() + ].sort((a, b)=>{ + if (a.hostId === 'local') return -1; + if (b.hostId === 'local') return 1; + return a.hostId.localeCompare(b.hostId); + }); + } function collectHostNames(data) { const names = new Map(); for (const [key, value] of Object.entries(data)){ @@ -10162,6 +10511,7 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Hx: ()=>listRemoteThreadsFromState, KI: ()=>findRemoteThread, + Kl: ()=>listDiscoveredHosts, XI: ()=>findRemoteThreadHostId }); }, @@ -10179,6 +10529,7 @@ var __webpack_modules__ = { port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const searchThreadsSchema = zod__rspack_import_4.Ikc({ @@ -10186,8 +10537,12 @@ var __webpack_modules__ = { query: zod__rspack_import_4.YjP().min(1).max(512), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); + const listHostsSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional() + }).strict(); const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, @@ -10276,6 +10631,7 @@ var __webpack_modules__ = { const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ limit: input.limit, host: input.host, + modelProvider: input.modelProvider, groupBy: input.groupBy })); return asResult({ @@ -10296,6 +10652,7 @@ var __webpack_modules__ = { query: input.query, limit: input.limit, host: input.host, + modelProvider: input.modelProvider, groupBy: input.groupBy }); }); @@ -10307,6 +10664,22 @@ var __webpack_modules__ = { return mapError(error); } } + async function listHostsOperation(input) { + try { + const out = await withAdapter(input.port, async (adapter)=>{ + if (typeof adapter.listHosts !== 'function') { + throw new _errors_js__rspack_import_1.EH('listHosts', 'adapter does not implement listHosts'); + } + return adapter.listHosts(); + }); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } async function readThreadOperation(input) { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ @@ -10360,9 +10733,15 @@ var __webpack_modules__ = { return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); + if (Array.isArray(result.hosts)) { + const providers = Array.isArray(result.modelProviders) ? ` providers=${result.modelProviders.length} (${String(result.modelProvidersSource ?? '')})` : ''; + return `${result.hosts.length} hosts via ${String(result.hostsSource ?? result.backend ?? 'unknown')}${providers}`; + } if (Array.isArray(result.threads)) { const via = result.query ? ` matching ${JSON.stringify(result.query)}` : ''; - return `${result.threads.length} threads${via} via ${result.backend ?? 'unknown'}`; + const host = result.host && result.host !== 'all' ? ` host=${result.host}` : ''; + const provider = result.modelProvider ? ` provider=${result.modelProvider}` : ''; + return `${result.threads.length} threads${via}${host}${provider} via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { const mode = result.full ? 'full' : 'page'; @@ -10379,6 +10758,7 @@ var __webpack_modules__ = { return JSON.stringify(result); } __webpack_require__.d(__webpack_exports__, { + Bm: ()=>listHostsOperation, D6: ()=>resultText, UK: ()=>readThreadOperation, UP: ()=>sendOperation, @@ -10390,6 +10770,7 @@ var __webpack_modules__ = { FC: listThreadsSchema, FD: resultSchema, Fn: waitReplySchema, + Rf: listHostsSchema, Wi: sendSchema, aW: statusSchema, nl: searchThreadsSchema, @@ -11010,6 +11391,45 @@ var __webpack_modules__ = { yF: withRedactedErrors }); }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop list hosts', + description: 'Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.Rf, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number' + } + }, + required: [] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.Bm)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.Rf + }, { + "default": __rspack_default_export + }); + }, "./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); @@ -11018,7 +11438,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List ChatGPT Desktop / Codex threads: local app-server thread/list (modelProviders:[]) merged with remote-control summaries from ~/.codex/.codex-global-state.json (remote-thread-summaries-v3:). Each thread has location local|remote and hostId/hostName. Optional host filter and groupBy=host. Merges CDP selected when connected. Result includes backend.', + description: 'List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.', annotations: { readOnlyHint: true }, @@ -11037,7 +11457,11 @@ var __webpack_modules__ = { }, host: { type: 'string', - description: 'Filter by hostId or friendly host/env name (use "local" for local-only).' + description: 'Machine/location filter: "all" (default), "local", or a hostId / friendly name from chatgpt_desktop_list_hosts.' + }, + modelProvider: { + type: 'string', + description: 'Filter passed through to app-server thread/list modelProviders. Omit for all providers.' }, groupBy: { type: 'string', @@ -11131,7 +11555,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop search threads', - description: 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries in ~/.codex/.codex-global-state.json. Optional host filter and groupBy=host. Merges CDP selected/pinned when connected. Result includes backend.', + description: 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.', annotations: { readOnlyHint: true }, @@ -11154,7 +11578,11 @@ var __webpack_modules__ = { }, host: { type: 'string', - description: 'Filter by hostId or friendly host/env name (use "local" for local-only).' + description: 'Machine/location filter: "all" (default), "local", or a hostId / friendly name from chatgpt_desktop_list_hosts.' + }, + modelProvider: { + type: 'string', + description: 'Filter passed through to app-server thread/list modelProviders. Omit for all providers.' }, groupBy: { type: 'string', @@ -24005,17 +24433,20 @@ var __webpack_modules__ = { }; } const THREAD_LIST_MAX_LIMIT = 200; - async function listCodexThreads({ limit = 20, cursor, env = process.env } = {}) { + async function listCodexThreads({ limit = 20, cursor, modelProviders = [], env = process.env } = {}) { if (!Number.isInteger(limit) || limit < 1 || limit > THREAD_LIST_MAX_LIMIT) { throw new RangeError("--limit must be an integer 1-" + THREAD_LIST_MAX_LIMIT); } if (cursor !== undefined && (typeof cursor !== "string" || !cursor)) throw new RangeError("--cursor must be a non-empty string"); + if (!Array.isArray(modelProviders) || modelProviders.some((p)=>typeof p !== "string")) { + throw new RangeError("modelProviders must be an array of strings (empty = all providers)"); + } const { client } = await openSession(env); try { const params = { limit, useStateDbOnly: true, - modelProviders: [], + modelProviders, ...cursor !== undefined ? { cursor } : {} @@ -26954,49 +27385,51 @@ function __webpack_require__(moduleId) { var __webpack_exports__ = {}; var node_worker_threads__rspack_import_0 = __webpack_require__("node:worker_threads"); var react__rspack_import_1 = __webpack_require__("./node_modules/react/react.react-server.js"); -var _agent_bundle_runtime_flight_server__rspack_import_25 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); -var _agent_bundle_runtime__rspack_import_22 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); -var _agent_bundle_runtime__rspack_import_23 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); -var _agent_bundle_runtime__rspack_import_24 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); +var _agent_bundle_runtime_flight_server__rspack_import_26 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); +var _agent_bundle_runtime__rspack_import_23 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); +var _agent_bundle_runtime__rspack_import_24 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); +var _agent_bundle_runtime__rspack_import_25 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); var node_url__rspack_import_2 = __webpack_require__("node:url"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); -var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); -var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); -var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); -var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); -var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); -var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); -var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); -var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); -var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); -var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); -var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); -var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); -var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_21 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); -const route0 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3); -const route1 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4); -const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_5); -const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_6); -const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_7); -const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_8); -const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_9); -const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_10); -const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_11); -const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_12); -const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_13); -const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_14); -const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_15); -const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_16); -const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_17); -const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_18); -const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_19); -const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_20); -const route18 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_21, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_21); +var _src_mcp_grok_bot_tools_chatgpt_desktop_list_hosts_tsx__rspack_import_3 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_4 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); +var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); +var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); +var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); +var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); +var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); +var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); +var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); +var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); +var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); +var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); +var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); +var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_21 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); +var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_22 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); +const route0 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_hosts_tsx__rspack_import_3, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_hosts_tsx__rspack_import_3); +const route1 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_4, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_4); +const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_5); +const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_6); +const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_7); +const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_8); +const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_9); +const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_10); +const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_11); +const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_12); +const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_13); +const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_14); +const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_15); +const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_16); +const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_17); +const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_18); +const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_19); +const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_20); +const route18 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_21, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_21); +const route19 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_22, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_22); globalThis.__rspack_rsc_manifest__ ??= Object.freeze({ clientManifest: Object.freeze({}) }); @@ -27008,18 +27441,42 @@ const processLifetime = { instanceId: crypto.randomUUID(), pid: process.pid }; -const pluginRoot = (0, _agent_bundle_runtime__rspack_import_22.E7)({ +const pluginRoot = (0, _agent_bundle_runtime__rspack_import_23.E7)({ fallback: (0, node_url__rspack_import_2.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); const composeLayouts = (route, props)=>(0, react__rspack_import_1.createElement)(route.module.default, props); const routes = Object.freeze({ + "tool:grok-bot/chatgpt_desktop_list_hosts": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "port": { + "type": "number" + } + }, + "required": [], + "type": "object" + }, + "title": "ChatGPT Desktop list hosts" + }, + id: "tool:grok-bot/chatgpt_desktop_list_hosts", + kind: "tool", + module: route0, + name: "chatgpt_desktop_list_hosts", + serverId: "mcp:grok-bot" + }), "tool:grok-bot/chatgpt_desktop_list_threads": Object.freeze({ config: { "annotations": { "readOnlyHint": true }, - "description": "List ChatGPT Desktop / Codex threads: local app-server thread/list (modelProviders:[]) merged with remote-control summaries from ~/.codex/.codex-global-state.json (remote-thread-summaries-v3:). Each thread has location local|remote and hostId/hostName. Optional host filter and groupBy=host. Merges CDP selected when connected. Result includes backend.", + "description": "List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -27031,13 +27488,17 @@ const routes = Object.freeze({ "type": "string" }, "host": { - "description": "Filter by hostId or friendly host/env name (use \"local\" for local-only).", + "description": "Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.", "type": "string" }, "limit": { "description": "Maximum threads (1-200).", "type": "number" }, + "modelProvider": { + "description": "Filter passed through to app-server thread/list modelProviders. Omit for all providers.", + "type": "string" + }, "port": { "type": "number" } @@ -27049,7 +27510,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_list_threads", kind: "tool", - module: route0, + module: route1, name: "chatgpt_desktop_list_threads", serverId: "mcp:grok-bot" }), @@ -27093,7 +27554,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_read_thread", kind: "tool", - module: route1, + module: route2, name: "chatgpt_desktop_read_thread", serverId: "mcp:grok-bot" }), @@ -27102,7 +27563,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries in ~/.codex/.codex-global-state.json. Optional host filter and groupBy=host. Merges CDP selected/pinned when connected. Result includes backend.", + "description": "Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -27114,13 +27575,17 @@ const routes = Object.freeze({ "type": "string" }, "host": { - "description": "Filter by hostId or friendly host/env name (use \"local\" for local-only).", + "description": "Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.", "type": "string" }, "limit": { "description": "Maximum matches (1-200).", "type": "number" }, + "modelProvider": { + "description": "Filter passed through to app-server thread/list modelProviders. Omit for all providers.", + "type": "string" + }, "port": { "type": "number" }, @@ -27138,7 +27603,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_search_threads", kind: "tool", - module: route2, + module: route3, name: "chatgpt_desktop_search_threads", serverId: "mcp:grok-bot" }), @@ -27181,7 +27646,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_send", kind: "tool", - module: route3, + module: route4, name: "chatgpt_desktop_send", serverId: "mcp:grok-bot" }), @@ -27206,7 +27671,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_status", kind: "tool", - module: route4, + module: route5, name: "chatgpt_desktop_status", serverId: "mcp:grok-bot" }), @@ -27239,7 +27704,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_wait_reply", kind: "tool", - module: route5, + module: route6, name: "chatgpt_desktop_wait_reply", serverId: "mcp:grok-bot" }), @@ -27275,7 +27740,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/claude_send", kind: "tool", - module: route6, + module: route7, name: "claude_send", serverId: "mcp:grok-bot" }), @@ -27356,7 +27821,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_send", kind: "tool", - module: route7, + module: route8, name: "codex_send", serverId: "mcp:grok-bot" }), @@ -27390,7 +27855,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_threads", kind: "tool", - module: route8, + module: route9, name: "codex_threads", serverId: "mcp:grok-bot" }), @@ -27440,7 +27905,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_wait", kind: "tool", - module: route9, + module: route10, name: "codex_wait", serverId: "mcp:grok-bot" }), @@ -27483,7 +27948,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_watch", kind: "tool", - module: route10, + module: route11, name: "codex_watch", serverId: "mcp:grok-bot" }), @@ -27525,7 +27990,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_bridge_start", kind: "tool", - module: route11, + module: route12, name: "gbot_bridge_start", serverId: "mcp:grok-bot" }), @@ -27551,7 +28016,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_bridge_status", kind: "tool", - module: route12, + module: route13, name: "gbot_bridge_status", serverId: "mcp:grok-bot" }), @@ -27580,7 +28045,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_bridge_stop", kind: "tool", - module: route13, + module: route14, name: "gbot_bridge_stop", serverId: "mcp:grok-bot" }), @@ -27639,7 +28104,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_codex_respond", kind: "tool", - module: route14, + module: route15, name: "gbot_codex_respond", serverId: "mcp:grok-bot" }), @@ -27670,7 +28135,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_grok_approvals", kind: "tool", - module: route15, + module: route16, name: "gbot_grok_approvals", serverId: "mcp:grok-bot" }), @@ -27717,7 +28182,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_grok_respond", kind: "tool", - module: route16, + module: route17, name: "gbot_grok_respond", serverId: "mcp:grok-bot" }), @@ -27778,7 +28243,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_send", kind: "tool", - module: route17, + module: route18, name: "gbot_send", serverId: "mcp:grok-bot" }), @@ -27824,7 +28289,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_thread", kind: "tool", - module: route18, + module: route19, name: "gbot_thread", serverId: "mcp:grok-bot" }) @@ -27872,7 +28337,7 @@ const render = async (message)=>{ }; try { const plugin = message.plugin ?? pluginRoot.identity; - await (0, _agent_bundle_runtime__rspack_import_23.iC)({ + await (0, _agent_bundle_runtime__rspack_import_24.iC)({ ...message.actor === undefined ? {} : { actor: message.actor }, @@ -27886,7 +28351,7 @@ const render = async (message)=>{ operationId: route.id, surface: route.name }, - lineage: message.lineage ?? (0, _agent_bundle_runtime__rspack_import_23.hU)('not-provided'), + lineage: message.lineage ?? (0, _agent_bundle_runtime__rspack_import_24.hU)('not-provided'), plugin, progress: { report: async (update)=>{ @@ -27902,7 +28367,7 @@ const render = async (message)=>{ session: message.session }, signal: controller.signal, - terminal: message.terminal ?? (0, _agent_bundle_runtime__rspack_import_23.hU)('not-provided'), + terminal: message.terminal ?? (0, _agent_bundle_runtime__rspack_import_24.hU)('not-provided'), ...message.workspace === undefined ? {} : { workspace: message.workspace } @@ -27937,10 +28402,10 @@ const render = async (message)=>{ type: 'observed-render-start' }); const renderStartedAt = performance.now(); - const element = validationError === undefined ? composeLayouts(observedRoute, props, controller.signal) : (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_24.g.Result, null, (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_24.g.Error, { + const element = validationError === undefined ? composeLayouts(observedRoute, props, controller.signal) : (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_25.g.Result, null, (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_25.g.Error, { code: 'invalid-input' }, `Input validation error: ${validationError instanceof Error ? validationError.message : String(validationError)}`)); - const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_25.y)(element, { + const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_26.y)(element, { signal: controller.signal }); const reader = flight.getReader(); diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index 683081b..da9edbe 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -6497,23 +6497,26 @@ var __webpack_modules__ = { var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _remote_threads_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); - async function appServerListThreads({ limit = 50, cursor } = {}) { + async function appServerListThreads({ limit = 50, cursor, modelProviders = [] } = {}) { const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit, - cursor + cursor, + modelProviders }); return { backend: 'app-server', limit: out.limit, nextCursor: out.nextCursor ?? null, - threads: out.threads.map(mapListedThread) + threads: out.threads.map(mapListedThread), + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } - async function appServerSearchThreads({ query, limit = 50 }) { + async function appServerSearchThreads({ query, limit = 50, modelProviders = [] }) { const needle = query.trim().toLowerCase(); if (!needle) { return appServerListThreads({ - limit + limit, + modelProviders }); } const matched = []; @@ -6521,7 +6524,8 @@ var __webpack_modules__ = { for(let page = 0; page < 20 && matched.length < limit; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit: 200, - cursor + cursor, + modelProviders }); for (const thread of out.threads){ const mapped = mapListedThread(thread); @@ -6536,9 +6540,180 @@ var __webpack_modules__ = { limit, query, nextCursor: null, - threads: matched.slice(0, limit) + threads: matched.slice(0, limit), + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined + }; + } + const MODEL_PROVIDER_LIST_METHODS = [ + 'modelProvider/list', + 'model/providers/list', + 'models/providers/list', + 'account/modelProviders/list', + 'config/modelProviders/list', + 'provider/list' + ]; + const REMOTE_ENVIRONMENT_LIST_METHODS = [ + 'remoteEnvironment/list', + 'remote/environments/list', + 'environment/list', + 'remoteControl/hosts/list', + 'remote/hosts/list', + 'hosts/list' + ]; + async function discoverModelProviders() { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + for (const method of MODEL_PROVIDER_LIST_METHODS){ + try { + const result = await client.request(method, {}); + const providers = normalizeNamedList(result, [ + 'id', + 'name', + 'provider', + 'modelProvider', + 'slug' + ]); + if (providers.length > 0) { + return { + providers, + source: `app-server:${method}` + }; + } + } catch {} + } + } finally{ + client.close(); + } + const providers = new Set(); + let cursor; + for(let page = 0; page < 20; page++){ + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit: 200, + cursor, + modelProviders: [] + }); + for (const thread of out.threads){ + if (typeof thread.modelProvider === 'string' && thread.modelProvider) { + providers.add(thread.modelProvider); + } + } + if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + cursor = out.nextCursor; + } + return { + providers: [ + ...providers + ].sort(), + source: 'thread/list-distinct' + }; + } + async function discoverRemoteEnvironments() { + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + for (const method of REMOTE_ENVIRONMENT_LIST_METHODS){ + try { + const result = await client.request(method, {}); + const hosts = normalizeHostEntries(result); + if (hosts.length > 0) { + return { + hosts, + source: `app-server:${method}` + }; + } + } catch {} + } + } finally{ + client.close(); + } + return { + hosts: [], + source: null }; } + function normalizeNamedList(result, idKeys) { + const raw = listPayload(result); + const out = []; + for (const entry of raw){ + if (typeof entry === 'string' && entry) out.push(entry); + else if (entry && typeof entry === 'object') { + const row = entry; + for (const key of idKeys){ + if (typeof row[key] === 'string' && row[key]) { + out.push(String(row[key])); + break; + } + } + } + } + return [ + ...new Set(out) + ].sort(); + } + function normalizeHostEntries(result) { + const raw = listPayload(result); + const out = []; + for (const entry of raw){ + if (typeof entry === 'string' && entry) { + out.push({ + hostId: entry, + hostName: null + }); + continue; + } + if (!entry || typeof entry !== 'object') continue; + const row = entry; + let hostId = null; + for (const key of [ + 'hostId', + 'id', + 'uuid', + 'environmentId', + 'envId' + ]){ + if (typeof row[key] === 'string' && row[key]) { + hostId = String(row[key]); + break; + } + } + if (!hostId) continue; + let hostName = null; + for (const key of [ + 'hostName', + 'name', + 'displayName', + 'envName', + 'label', + 'title' + ]){ + if (typeof row[key] === 'string' && row[key]) { + hostName = String(row[key]); + break; + } + } + out.push({ + hostId, + hostName + }); + } + return out; + } + function listPayload(result) { + if (Array.isArray(result)) return result; + if (!result || typeof result !== 'object') return []; + const record = result; + for (const key of [ + 'data', + 'providers', + 'modelProviders', + 'hosts', + 'environments', + 'remoteEnvironments', + 'items' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + return []; + } async function appServerReadThread({ threadId, limit = 100, full = false }) { const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); @@ -6864,6 +7039,8 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, + OP: ()=>discoverRemoteEnvironments, + X: ()=>discoverModelProviders, aI: ()=>appServerSearchThreads, dM: ()=>appServerStatusProbe }); @@ -7776,7 +7953,10 @@ var __webpack_modules__ = { searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, statusProbe: _app_server_fallback_js__rspack_import_1.dM, - listRemoteThreads: _remote_threads_js__rspack_import_4.Hx + listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, + listHosts: _remote_threads_js__rspack_import_4.Kl, + discoverModelProviders: _app_server_fallback_js__rspack_import_1.X, + discoverRemoteEnvironments: _app_server_fallback_js__rspack_import_1.OP }; class ChatGptDesktopFacade { #cdp; @@ -7806,11 +7986,14 @@ var __webpack_modules__ = { } async listThreads(options = {}) { const limit = options.limit ?? 50; + const host = normalizeHostFilter(options.host); + const modelProviders = modelProvidersFromFilter(options.modelProvider); let appList = null; let appError; try { appList = await this.#fallbacks.listThreads({ - limit + limit, + modelProviders }); } catch (error) { appError = error; @@ -7838,17 +8021,107 @@ var __webpack_modules__ = { else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); return finalizeThreadList(base, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: this.#listRemotes() }); } + async listHosts() { + const remotes = this.#listRemotes(); + let localThreadCount = 0; + try { + const local = await this.#fallbacks.listThreads({ + limit: 200, + modelProviders: [] + }); + localThreadCount = local.threads.length; + } catch { + localThreadCount = 0; + } + const listHosts = this.#fallbacks.listHosts ?? _remote_threads_js__rspack_import_4.Kl; + const fromState = listHosts(process.env, { + localThreadCount + }); + const byId = new Map(fromState.map((host)=>[ + host.hostId, + { + ...host + } + ])); + let hostsSource = 'remote-thread-summaries-v3+local'; + try { + const discoverEnvs = this.#fallbacks.discoverRemoteEnvironments ?? _app_server_fallback_js__rspack_import_1.OP; + const appHosts = await discoverEnvs(); + if (appHosts.source && appHosts.hosts.length > 0) { + for (const host of appHosts.hosts){ + const existing = byId.get(host.hostId); + if (existing) { + byId.set(host.hostId, { + ...existing, + hostName: existing.hostName ?? host.hostName + }); + } else { + byId.set(host.hostId, { + hostId: host.hostId, + hostName: host.hostName, + location: 'remote', + threadCount: 0 + }); + } + } + hostsSource = `${appHosts.source}+remote-thread-summaries-v3+local`; + } + } catch {} + const remoteCounts = new Map(); + for (const thread of remotes){ + remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + } + const withCounts = [ + ...byId.values() + ].map((host)=>host.hostId === 'local' ? { + ...host, + threadCount: localThreadCount + } : { + ...host, + threadCount: remoteCounts.get(host.hostId) ?? host.threadCount + }).sort((a, b)=>{ + if (a.hostId === 'local') return -1; + if (b.hostId === 'local') return 1; + return a.hostId.localeCompare(b.hostId); + }); + let modelProviders = []; + let modelProvidersSource = 'thread/list-distinct'; + try { + const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_1.X; + const discovered = await discover(); + modelProviders = [ + ...discovered.providers + ]; + modelProvidersSource = discovered.source; + } catch { + modelProviders = [ + ...new Set(remotes.map((thread)=>thread.modelProvider).filter((value)=>typeof value === 'string' && Boolean(value))) + ].sort(); + modelProvidersSource = 'remote-summaries-distinct'; + } + return { + hosts: withCounts, + hostsSource, + modelProviders, + modelProvidersSource, + backend: 'app-server' + }; + } async searchThreads(options) { const limit = options.limit ?? 50; + const host = normalizeHostFilter(options.host); + const modelProviders = modelProvidersFromFilter(options.modelProvider); try { const appList = await this.#fallbacks.searchThreads({ query: options.query, - limit + limit, + modelProviders }); const cdpList = await this.#tryCdpList({ limit @@ -7856,7 +8129,8 @@ var __webpack_modules__ = { const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; const withRemotes = finalizeThreadList(base, { limit: 10000, - host: options.host, + host, + modelProvider: options.modelProvider, remotes: this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); @@ -7867,7 +8141,8 @@ var __webpack_modules__ = { }; return finalizeThreadList(filtered, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: [] }); @@ -7884,7 +8159,8 @@ var __webpack_modules__ = { }; return finalizeThreadList(filtered, { limit, - host: options.host, + host, + modelProvider: options.modelProvider, groupBy: options.groupBy, remotes: this.#listRemotes() }); @@ -8036,7 +8312,7 @@ var __webpack_modules__ = { threads: merged }; } - function finalizeThreadList(base, { limit, host, groupBy, remotes }) { + function finalizeThreadList(base, { limit, host = 'all', modelProvider, groupBy, remotes }) { const locals = base.threads.map((thread)=>{ const location = thread.location ?? 'local'; return { @@ -8060,7 +8336,11 @@ var __webpack_modules__ = { hostName: remote.hostName ?? null }); } - const filtered = host ? merged.filter((thread)=>hostMatches(thread, host)) : merged; + const filtered = merged.filter((thread)=>{ + if (!hostMatches(thread, host)) return false; + if (!modelProviderMatches(thread, modelProvider)) return false; + return true; + }); const limited = filtered.slice(0, limit); const result = { backend: base.backend, @@ -8072,8 +8352,9 @@ var __webpack_modules__ = { ...base.query !== undefined ? { query: base.query } : {}, - ...host ? { - host + host, + ...modelProvider ? { + modelProvider } : {} }; if (groupBy === 'host') { @@ -8109,15 +8390,32 @@ var __webpack_modules__ = { ...groups.values() ]; } + function normalizeHostFilter(host) { + const value = (host ?? 'all').trim(); + return value || 'all'; + } + function modelProvidersFromFilter(modelProvider) { + if (!modelProvider || !modelProvider.trim()) return []; + return [ + modelProvider.trim() + ]; + } function hostMatches(thread, host) { const needle = host.trim().toLowerCase(); - if (!needle) return true; + if (!needle || needle === 'all') return true; if (needle === 'local') return (thread.location ?? 'local') === 'local'; return [ thread.hostId, thread.hostName ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); } + function modelProviderMatches(thread, modelProvider) { + if (!modelProvider) return true; + if (!thread.modelProvider) { + return thread.location === 'remote'; + } + return thread.modelProvider === modelProvider; + } function threadMatchesQuery(thread, needle) { if (!needle) return true; return [ @@ -8282,6 +8580,57 @@ var __webpack_modules__ = { function findRemoteThreadHostId(threadId, env = process.env) { return findRemoteThread(threadId, env)?.hostId ?? null; } + function listDiscoveredHosts(env = process.env, { localThreadCount = 0 } = {}) { + const remotes = listRemoteThreadsFromState(env); + const byHost = new Map(); + byHost.set('local', { + hostId: 'local', + hostName: 'local', + location: 'local', + threadCount: localThreadCount + }); + const data = loadCodexGlobalState(env); + if (data) { + const hostNames = collectHostNames(data); + for (const key of Object.keys(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match?.[1]) continue; + const hostId = match[1]; + const summary = data[key]; + const hostName = hostNames.get(hostId) ?? extractHostName(summary) ?? null; + byHost.set(hostId, { + hostId, + hostName, + location: 'remote', + threadCount: 0 + }); + } + } + for (const thread of remotes){ + const existing = byHost.get(thread.hostId); + if (existing) { + byHost.set(thread.hostId, { + ...existing, + hostName: existing.hostName ?? thread.hostName, + threadCount: existing.threadCount + 1 + }); + } else { + byHost.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName, + location: 'remote', + threadCount: 1 + }); + } + } + return [ + ...byHost.values() + ].sort((a, b)=>{ + if (a.hostId === 'local') return -1; + if (b.hostId === 'local') return 1; + return a.hostId.localeCompare(b.hostId); + }); + } function collectHostNames(data) { const names = new Map(); for (const [key, value] of Object.entries(data)){ @@ -8570,6 +8919,7 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Hx: ()=>listRemoteThreadsFromState, KI: ()=>findRemoteThread, + Kl: ()=>listDiscoveredHosts, XI: ()=>findRemoteThreadHostId }); }, @@ -8587,6 +8937,7 @@ var __webpack_modules__ = { port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const searchThreadsSchema = zod__rspack_import_4.Ikc({ @@ -8594,8 +8945,12 @@ var __webpack_modules__ = { query: zod__rspack_import_4.YjP().min(1).max(512), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), + modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); + const listHostsSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional() + }).strict(); const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, @@ -8684,6 +9039,7 @@ var __webpack_modules__ = { const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ limit: input.limit, host: input.host, + modelProvider: input.modelProvider, groupBy: input.groupBy })); return asResult({ @@ -8704,6 +9060,7 @@ var __webpack_modules__ = { query: input.query, limit: input.limit, host: input.host, + modelProvider: input.modelProvider, groupBy: input.groupBy }); }); @@ -8715,6 +9072,22 @@ var __webpack_modules__ = { return mapError(error); } } + async function listHostsOperation(input) { + try { + const out = await withAdapter(input.port, async (adapter)=>{ + if (typeof adapter.listHosts !== 'function') { + throw new _errors_js__rspack_import_1.EH('listHosts', 'adapter does not implement listHosts'); + } + return adapter.listHosts(); + }); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } async function readThreadOperation(input) { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ @@ -8768,9 +9141,15 @@ var __webpack_modules__ = { return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); + if (Array.isArray(result.hosts)) { + const providers = Array.isArray(result.modelProviders) ? ` providers=${result.modelProviders.length} (${String(result.modelProvidersSource ?? '')})` : ''; + return `${result.hosts.length} hosts via ${String(result.hostsSource ?? result.backend ?? 'unknown')}${providers}`; + } if (Array.isArray(result.threads)) { const via = result.query ? ` matching ${JSON.stringify(result.query)}` : ''; - return `${result.threads.length} threads${via} via ${result.backend ?? 'unknown'}`; + const host = result.host && result.host !== 'all' ? ` host=${result.host}` : ''; + const provider = result.modelProvider ? ` provider=${result.modelProvider}` : ''; + return `${result.threads.length} threads${via}${host}${provider} via ${result.backend ?? 'unknown'}`; } if (Array.isArray(result.turns)) { const mode = result.full ? 'full' : 'page'; @@ -8787,6 +9166,7 @@ var __webpack_modules__ = { return JSON.stringify(result); } __webpack_require__.d(__webpack_exports__, { + Bm: ()=>listHostsOperation, D6: ()=>resultText, UK: ()=>readThreadOperation, UP: ()=>sendOperation, @@ -8798,6 +9178,7 @@ var __webpack_modules__ = { FC: listThreadsSchema, FD: resultSchema, Fn: waitReplySchema, + Rf: listHostsSchema, Wi: sendSchema, aW: statusSchema, nl: searchThreadsSchema, @@ -9418,6 +9799,45 @@ var __webpack_modules__ = { yF: withRedactedErrors }); }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop list hosts', + description: 'Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.Rf, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number' + } + }, + required: [] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.Bm)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.Rf + }, { + "default": __rspack_default_export + }); + }, "./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); @@ -9426,7 +9846,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List ChatGPT Desktop / Codex threads: local app-server thread/list (modelProviders:[]) merged with remote-control summaries from ~/.codex/.codex-global-state.json (remote-thread-summaries-v3:). Each thread has location local|remote and hostId/hostName. Optional host filter and groupBy=host. Merges CDP selected when connected. Result includes backend.', + description: 'List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.', annotations: { readOnlyHint: true }, @@ -9445,7 +9865,11 @@ var __webpack_modules__ = { }, host: { type: 'string', - description: 'Filter by hostId or friendly host/env name (use "local" for local-only).' + description: 'Machine/location filter: "all" (default), "local", or a hostId / friendly name from chatgpt_desktop_list_hosts.' + }, + modelProvider: { + type: 'string', + description: 'Filter passed through to app-server thread/list modelProviders. Omit for all providers.' }, groupBy: { type: 'string', @@ -9539,7 +9963,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop search threads', - description: 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries in ~/.codex/.codex-global-state.json. Optional host filter and groupBy=host. Merges CDP selected/pinned when connected. Result includes backend.', + description: 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.', annotations: { readOnlyHint: true }, @@ -9562,7 +9986,11 @@ var __webpack_modules__ = { }, host: { type: 'string', - description: 'Filter by hostId or friendly host/env name (use "local" for local-only).' + description: 'Machine/location filter: "all" (default), "local", or a hostId / friendly name from chatgpt_desktop_list_hosts.' + }, + modelProvider: { + type: 'string', + description: 'Filter passed through to app-server thread/list modelProviders. Omit for all providers.' }, groupBy: { type: 'string', @@ -58826,64 +59254,89 @@ var __webpack_modules__ = { "./.agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var node_url__rspack_import_0 = __webpack_require__("node:url"); - var _agent_bundle_runtime__rspack_import_22 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); + var _agent_bundle_runtime__rspack_import_23 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); var agent_bundle_mcp_server_runtime__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/mcp-server-runtime.js"); - var _agent_bundle_runtime_lineage__rspack_import_23 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/lineage.js"); + var _agent_bundle_runtime_lineage__rspack_import_24 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/lineage.js"); var agent_bundle_mcp_apps__rspack_import_2 = __webpack_require__("./.agent-bundle-virtual/mcp-grok-bot-b8c2461e-0.mjs"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); - var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); - var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); - var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); - var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); - var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); - var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); - var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); - var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); - var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); - var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); - var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); - var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); - var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_21 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); - const route0 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_3); - const route1 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_4); - const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_5); - const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_6); - const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_7); - const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_8); - const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_9); - const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_10); - const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_11); - const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_12); - const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_13); - const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_14); - const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_15); - const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_16); - const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_17); - const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_18); - const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_19); - const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_20); - const route18 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_21, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_21); + var _src_mcp_grok_bot_tools_chatgpt_desktop_list_hosts_tsx__rspack_import_3 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_4 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); + var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); + var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); + var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); + var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); + var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); + var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); + var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); + var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); + var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); + var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); + var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); + var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_21 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); + var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_22 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); + const route0 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_hosts_tsx__rspack_import_3, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_hosts_tsx__rspack_import_3); + const route1 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_4, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_4); + const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_5); + const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_6); + const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_7); + const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_8); + const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_9); + const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_10); + const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_11); + const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_12); + const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_13); + const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_14); + const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_15); + const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_16); + const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_17); + const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_18); + const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_19); + const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_20); + const route18 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_21, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_21); + const route19 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_22, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_22); const ARTIFACT_EPOCH = "gbot@0.10.1"; - const pluginRoot = (0, _agent_bundle_runtime__rspack_import_22.E7)({ + const pluginRoot = (0, _agent_bundle_runtime__rspack_import_23.E7)({ fallback: (0, node_url__rspack_import_0.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); const openLineage = async ()=>({ dispose: async ()=>undefined, - registry: (0, _agent_bundle_runtime_lineage__rspack_import_23.Q5)() + registry: (0, _agent_bundle_runtime_lineage__rspack_import_24.Q5)() }); const routes = Object.freeze({ + "tool:grok-bot/chatgpt_desktop_list_hosts": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "port": { + "type": "number" + } + }, + "required": [], + "type": "object" + }, + "title": "ChatGPT Desktop list hosts" + }, + id: "tool:grok-bot/chatgpt_desktop_list_hosts", + kind: "tool", + module: route0, + name: "chatgpt_desktop_list_hosts" + }), "tool:grok-bot/chatgpt_desktop_list_threads": Object.freeze({ config: { "annotations": { "readOnlyHint": true }, - "description": "List ChatGPT Desktop / Codex threads: local app-server thread/list (modelProviders:[]) merged with remote-control summaries from ~/.codex/.codex-global-state.json (remote-thread-summaries-v3:). Each thread has location local|remote and hostId/hostName. Optional host filter and groupBy=host. Merges CDP selected when connected. Result includes backend.", + "description": "List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -58895,13 +59348,17 @@ var __webpack_modules__ = { "type": "string" }, "host": { - "description": "Filter by hostId or friendly host/env name (use \"local\" for local-only).", + "description": "Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.", "type": "string" }, "limit": { "description": "Maximum threads (1-200).", "type": "number" }, + "modelProvider": { + "description": "Filter passed through to app-server thread/list modelProviders. Omit for all providers.", + "type": "string" + }, "port": { "type": "number" } @@ -58913,7 +59370,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_list_threads", kind: "tool", - module: route0, + module: route1, name: "chatgpt_desktop_list_threads" }), "tool:grok-bot/chatgpt_desktop_read_thread": Object.freeze({ @@ -58956,7 +59413,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_read_thread", kind: "tool", - module: route1, + module: route2, name: "chatgpt_desktop_read_thread" }), "tool:grok-bot/chatgpt_desktop_search_threads": Object.freeze({ @@ -58964,7 +59421,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries in ~/.codex/.codex-global-state.json. Optional host filter and groupBy=host. Merges CDP selected/pinned when connected. Result includes backend.", + "description": "Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -58976,13 +59433,17 @@ var __webpack_modules__ = { "type": "string" }, "host": { - "description": "Filter by hostId or friendly host/env name (use \"local\" for local-only).", + "description": "Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.", "type": "string" }, "limit": { "description": "Maximum matches (1-200).", "type": "number" }, + "modelProvider": { + "description": "Filter passed through to app-server thread/list modelProviders. Omit for all providers.", + "type": "string" + }, "port": { "type": "number" }, @@ -59000,7 +59461,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_search_threads", kind: "tool", - module: route2, + module: route3, name: "chatgpt_desktop_search_threads" }), "tool:grok-bot/chatgpt_desktop_send": Object.freeze({ @@ -59042,7 +59503,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_send", kind: "tool", - module: route3, + module: route4, name: "chatgpt_desktop_send" }), "tool:grok-bot/chatgpt_desktop_status": Object.freeze({ @@ -59066,7 +59527,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_status", kind: "tool", - module: route4, + module: route5, name: "chatgpt_desktop_status" }), "tool:grok-bot/chatgpt_desktop_wait_reply": Object.freeze({ @@ -59098,7 +59559,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_wait_reply", kind: "tool", - module: route5, + module: route6, name: "chatgpt_desktop_wait_reply" }), "tool:grok-bot/claude_send": Object.freeze({ @@ -59133,7 +59594,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/claude_send", kind: "tool", - module: route6, + module: route7, name: "claude_send" }), "tool:grok-bot/codex_send": Object.freeze({ @@ -59213,7 +59674,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_send", kind: "tool", - module: route7, + module: route8, name: "codex_send" }), "tool:grok-bot/codex_threads": Object.freeze({ @@ -59246,7 +59707,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_threads", kind: "tool", - module: route8, + module: route9, name: "codex_threads" }), "tool:grok-bot/codex_wait": Object.freeze({ @@ -59295,7 +59756,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_wait", kind: "tool", - module: route9, + module: route10, name: "codex_wait" }), "tool:grok-bot/codex_watch": Object.freeze({ @@ -59337,7 +59798,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_watch", kind: "tool", - module: route10, + module: route11, name: "codex_watch" }), "tool:grok-bot/gbot_bridge_start": Object.freeze({ @@ -59378,7 +59839,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_bridge_start", kind: "tool", - module: route11, + module: route12, name: "gbot_bridge_start" }), "tool:grok-bot/gbot_bridge_status": Object.freeze({ @@ -59403,7 +59864,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_bridge_status", kind: "tool", - module: route12, + module: route13, name: "gbot_bridge_status" }), "tool:grok-bot/gbot_bridge_stop": Object.freeze({ @@ -59431,7 +59892,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_bridge_stop", kind: "tool", - module: route13, + module: route14, name: "gbot_bridge_stop" }), "tool:grok-bot/gbot_codex_respond": Object.freeze({ @@ -59489,7 +59950,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_codex_respond", kind: "tool", - module: route14, + module: route15, name: "gbot_codex_respond" }), "tool:grok-bot/gbot_grok_approvals": Object.freeze({ @@ -59519,7 +59980,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_grok_approvals", kind: "tool", - module: route15, + module: route16, name: "gbot_grok_approvals" }), "tool:grok-bot/gbot_grok_respond": Object.freeze({ @@ -59565,7 +60026,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_grok_respond", kind: "tool", - module: route16, + module: route17, name: "gbot_grok_respond" }), "tool:grok-bot/gbot_send": Object.freeze({ @@ -59625,7 +60086,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_send", kind: "tool", - module: route17, + module: route18, name: "gbot_send" }), "tool:grok-bot/gbot_thread": Object.freeze({ @@ -59670,7 +60131,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_thread", kind: "tool", - module: route18, + module: route19, name: "gbot_thread" }) }); @@ -61012,17 +61473,20 @@ var __webpack_modules__ = { }; } const THREAD_LIST_MAX_LIMIT = 200; - async function listCodexThreads({ limit = 20, cursor, env = process.env } = {}) { + async function listCodexThreads({ limit = 20, cursor, modelProviders = [], env = process.env } = {}) { if (!Number.isInteger(limit) || limit < 1 || limit > THREAD_LIST_MAX_LIMIT) { throw new RangeError("--limit must be an integer 1-" + THREAD_LIST_MAX_LIMIT); } if (cursor !== undefined && (typeof cursor !== "string" || !cursor)) throw new RangeError("--cursor must be a non-empty string"); + if (!Array.isArray(modelProviders) || modelProviders.some((p)=>typeof p !== "string")) { + throw new RangeError("modelProviders must be an array of strings (empty = all providers)"); + } const { client } = await openSession(env); try { const params = { limit, useStateDbOnly: true, - modelProviders: [], + modelProviders, ...cursor !== undefined ? { cursor } : {} diff --git a/artifact/scripts/gbot-relay.mjs b/artifact/scripts/gbot-relay.mjs index 7131f93..b4e0677 100644 --- a/artifact/scripts/gbot-relay.mjs +++ b/artifact/scripts/gbot-relay.mjs @@ -23001,17 +23001,20 @@ var __webpack_modules__ = { }; } const THREAD_LIST_MAX_LIMIT = 200; - async function listCodexThreads({ limit = 20, cursor, env = process.env } = {}) { + async function listCodexThreads({ limit = 20, cursor, modelProviders = [], env = process.env } = {}) { if (!Number.isInteger(limit) || limit < 1 || limit > THREAD_LIST_MAX_LIMIT) { throw new RangeError("--limit must be an integer 1-" + THREAD_LIST_MAX_LIMIT); } if (cursor !== undefined && (typeof cursor !== "string" || !cursor)) throw new RangeError("--cursor must be a non-empty string"); + if (!Array.isArray(modelProviders) || modelProviders.some((p)=>typeof p !== "string")) { + throw new RangeError("modelProviders must be an array of strings (empty = all providers)"); + } const { client } = await openSession(env); try { const params = { limit, useStateDbOnly: true, - modelProviders: [], + modelProviders, ...cursor !== undefined ? { cursor } : {} diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index 1d990ae..7d2612b 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -163,6 +163,25 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { const fromState = listHosts(process.env, { localThreadCount }); const byId = new Map(fromState.map((host) => [host.hostId, { ...host }])); + // Ensure every host seen in merged remotes is present (tests / custom + // listRemoteThreads may supply rows without a matching global-state file). + for (const thread of remotes) { + const existing = byId.get(thread.hostId); + if (existing) { + byId.set(thread.hostId, { + ...existing, + hostName: existing.hostName ?? thread.hostName, + }); + } else { + byId.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName, + location: 'remote', + threadCount: 0, + }); + } + } + let hostsSource = 'remote-thread-summaries-v3+local'; try { const discoverEnvs = diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index 00295ba..2f9ddcf 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -42,7 +42,7 @@ function fakeAdapter(overrides: Partial = {}): ChatGptDes }, async listThreads({ limit = 50 } = {}) { return { - backend: 'cdp', + backend: 'cdp' as const, limit, host: 'all', threads: [ @@ -52,7 +52,7 @@ function fakeAdapter(overrides: Partial = {}): ChatGptDes pinned: false, selected: true, kind: 'local', - location: 'local', + location: 'local' as const, hostId: null, hostName: null, }, @@ -61,16 +61,16 @@ function fakeAdapter(overrides: Partial = {}): ChatGptDes }, async listHosts() { return { - backend: 'app-server', + backend: 'app-server' as const, hostsSource: 'remote-thread-summaries-v3+local', modelProviders: ['openai'], modelProvidersSource: 'thread/list-distinct', hosts: [ - { hostId: 'local', hostName: 'local', location: 'local', threadCount: 1 }, + { hostId: 'local', hostName: 'local', location: 'local' as const, threadCount: 1 }, { hostId: 'host-macbook', hostName: "Zack's MacBook", - location: 'remote', + location: 'remote' as const, threadCount: 2, }, ], From b71f10ed2f7167255389452850818b19233b719e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 01:42:08 +0000 Subject: [PATCH 13/26] fix: codex list/read/send bugs from desktop work - list-threads: modelProviders:[], nextCursor paging, useStateDbOnly with full-scan fallback when the state DB returns nothing - normalize Desktop local: thread ids on every codex threadId acceptor - map remote-control "thread not loaded" to REMOTE_THREAD_NOT_LOADED with hostId/hostName on codex send and conversation open - readCodexThread uses thread/read metadata + thread/turns/list (never deprecated includeTurns) - outcomeFromError forwards hostId/hint/code; allowlist matches normalized ids Co-authored-by: Zack Jackson --- .changeset/chatgpt-desktop-cdp.md | 2 +- README.md | 2 +- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 462 +++++++++++++++-- artifact/bin/gbot.mjs | 466 ++++++++++++++++-- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 463 +++++++++++++++-- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 460 +++++++++++++++-- artifact/scripts/gbot-relay.mjs | 381 +++++++++++++- src/cli/codex/list-threads.tsx | 6 +- src/core/chatgpt-desktop/errors.ts | 42 +- src/core/chatgpt-desktop/thread-ids.ts | 21 +- src/core/codex-bridge.js | 117 ++++- src/core/codex/contract.js | 5 +- src/core/codex/conversation.js | 9 +- src/core/codex/remote-control.js | 224 +++++++++ src/core/codex/routes.ts | 15 +- src/core/codex/thread-id.js | 47 ++ src/mcp/grok-bot/tools/codex_threads.tsx | 5 +- test/codex-bridge.test.js | 148 ++++++ test/host-tool-inventory.test.js | 1 + 21 files changed, 2612 insertions(+), 268 deletions(-) create mode 100644 src/core/codex/remote-control.js create mode 100644 src/core/codex/thread-id.js diff --git a/.changeset/chatgpt-desktop-cdp.md b/.changeset/chatgpt-desktop-cdp.md index 4b03937..cf39e5c 100644 --- a/.changeset/chatgpt-desktop-cdp.md +++ b/.changeset/chatgpt-desktop-cdp.md @@ -2,4 +2,4 @@ "grok-bot-cli": minor --- -Scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools (`chatgpt_desktop_*`). List/search keep separate `host` (`all`|`local`|id/name) and `modelProvider`→`modelProviders` filters. `chatgpt_desktop_list_hosts` / `gbot chatgpt-desktop hosts` discovers hosts from `remote-thread-summaries-v3` (+ optional app-server remote-env method) and modelProviders via app-server list method or distinct `thread/list`. Reports `hostsSource` / `modelProvidersSource`. Remote read returns typed error with host hint. Fixes `modelProviders: []` on list-threads. Reports `backend`. +Scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools (`chatgpt_desktop_*`). List/search keep separate `host` / `modelProvider` filters; `list_hosts` discovers hosts and providers. Codex list-threads always passes `modelProviders: []`, pages via `nextCursor`, and falls back from `useStateDbOnly` when empty. Codex send/read/wait strip Desktop `local:` ids; remote-control "thread not loaded" maps to `REMOTE_THREAD_NOT_LOADED` with host. Thread reads use `thread/read` metadata + `thread/turns/list` (never deprecated `includeTurns`). diff --git a/README.md b/README.md index 69eac6b..1040cbd 100644 --- a/README.md +++ b/README.md @@ -243,7 +243,7 @@ MCP tools: `chatgpt_desktop_status`, `chatgpt_desktop_list_threads`, `chatgpt_de `desktopShimConfigured` is true when the installed wrapper is selected by Desktop-facing `CODEX_CLI_PATH` (the GUI domain on macOS). This describes configuration for future launches; a running Desktop may not have inherited it, and the wrapper may have fallen back to stock Codex. `desktopAttached` is `"private-stdio"` when a Desktop-bundled app-server process is observed, otherwise `"unknown"`. That process observation and shim configuration can both be present. Neither a configured shim nor a reachable daemon proves Desktop is attached to that daemon. Verify actual attachment with a controlled shared-thread interaction and matching thread/turn IDs. -**Thread discovery.** `list-threads --limit N` (1–200) pages with the opaque `--cursor` from the previous `nextCursor`; JSON keeps the cursor verbatim, text output prints a sanitized `more: --cursor …` hint. Requests pass `modelProviders: []` so threads from every provider appear (the daemon otherwise filters to the current provider) and `useStateDbOnly: true` for a fast state-DB listing. Text fields are stripped of terminal control sequences in both outputs (single-line fields also lose line breaks; `preview` keeps its newlines; a structured `source` such as `{ "custom": … }` passes through unchanged), `status` is one of `notLoaded | idle | active | systemError | unknown`, and non-numeric `updatedAt` / `createdAt` become `null`. Extra fields when present: `section`, `projectId`, `modelProvider`, `model`, `originator`. Unknown arguments are rejected before the socket is touched; a response that does not match the pinned schema (including an entry without a string `id`) fails with `reason: "bad-response"`. +**Thread discovery.** `list-threads --limit N` (1–200) pages with the opaque `--cursor` from the previous `nextCursor`; JSON keeps the cursor verbatim, text output prints a sanitized `more: --cursor …` hint. Requests pass `modelProviders: []` so threads from every provider appear (the daemon otherwise filters to the current provider) and `useStateDbOnly: true` for a fast state-DB listing, falling back to a full scan when that first page is empty. Text fields are stripped of terminal control sequences in both outputs (single-line fields also lose line breaks; `preview` keeps its newlines; a structured `source` such as `{ "custom": … }` passes through unchanged), `status` is one of `notLoaded | idle | active | systemError | unknown`, and non-numeric `updatedAt` / `createdAt` become `null`. Extra fields when present: `section`, `projectId`, `modelProvider`, `model`, `originator`. Unknown arguments are rejected before the socket is touched; a response that does not match the pinned schema (including an entry without a string `id`) fails with `reason: "bad-response"`. **Routes, attribution, and loops.** `gbot codex send` runs on the machine that owns `CODEX_HOME`, as the user who owns the socket, with that user's Codex credentials; the socket path comes only from `CODEX_HOME` or `CODEX_APP_SERVER_SOCK`, never from the message or an agent-supplied argument. gbot has no remote transport. A cloud-hosted Grok Bot on the box cannot reach a desktop socket at `/home/box/.codex/...` — use Grok Bot Shell with a machineId to run `gbot` on the user's registered machine (after `codex app-server daemon start` / bootstrap there). `GROK_BOT_CODEX_THREADS=id,id` lets the operator pin `send` to approved threads (`reason: "route-not-allowed"` otherwise). Every send gets a delivery envelope: `messageId` (also sent as Codex's native `clientUserMessageId`), `correlationId` (defaults to the message id), optional `replyTo`, and `hop`. A reply passes the original correlation id and `hop` + 1: diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 82057bf..0977f8c 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"9de6133a4be254740f94b7adc0f127d1944af08699816b4f78d4c8b7465843dd"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"2db5083337425e528943c4eec837d81ff079c787573e41fe3b4610adad63111b"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"0607539fd2c35038761f036925a92fa656e27ac45acdb23721e64882fe04d556"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"f34c137c230bcc7b07cbc039ac7ee522a35c649851051cd171b09aecb04de523"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"956ee3ba0344d53f4bdaa2fa08fc30968dd1f90ec203088c4bf76507db537a31"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"59a193a8278b9fdd51fb47c4e02cc0c79c7a24fdf6d63bdaa3f44be8dcec23bf"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"9be8afe780425204731648c4555d9918b36eca3cc6dc692d202d3682c505c432"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"c2c85b5b9b1d9e3b6d6988fa4c53f60da14d44bd687ae4fc02303d22c3356c29"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"9149f1cfbd0748efe8cf327f2902b9174d27891e53083739857a51c332c3668e"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index c54c826..8937dec 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"20100872aa652400dfbd7e3a2e09377c0a6c53c6d710278de9d432d58179b3b4","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"3b68c5e6e360f88e0d10ab970ca5a76e74dd6ba9a70af7b998180e5b52aba118","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"321dfc46762ffeff35c4cdbe3905bd77593804b36fa07601929e1f48639362a2"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"1d3d8ed8ab8fe80184eb780262b5577cb26131a7b61b7e815737e9e412d8d4e6"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"f7c39813e719de53abbd4bd4dc99e3cc606253b3235ee04a9b346582bff771ce"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"1c03ed7644b8006a00b751ea3b97630e008e5896c3797ef0f1cb510b941c6234"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"6f9facafa101776ce7ddf4282a4f19edcfc40b76da251afa59f8e2f4350c9f33"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"21454ac9c648e0d130d40d1f15f9e909cf5c82eafa018e7a066a419b72cb0d41"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"4419b29c5bc56f019e2835e3c8dbf4bc72291150900cfe2b8781a94c1482fe0f"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"8be4849f9c85c392d3e989d222d714169da982c0337d57cdc3411d14084d9bf3"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"583279e0360f529405948a6fb33712dabaa9917bb616bd00dcc83a6b6422827c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"8a45cab48d9f02da4fa2118e0a238696ab2f4ee198faff45ac64580c1f687d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"98edba7908cecffb141018bc358074f2785baf84bd76c4e9564843d48ad9e2dd"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"a7304f85f284dd0724475fed292a4ea17714b49061a0f6a6921d0d9899b1fa05"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"44e9ee4c29ba2276e2a8d946275e54aec0645f55cd9d63413ac16f59d1a68d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"694159395711268403159676c679a6a0d939bbaff546b673136f0ce4a67d686a"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"f4843da5a5fde4728e2dfe6766be0ce29b50a45af8a9508df8fcf86dffaee651"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"8463e5a981dcc4f67b386c5f1b97504905ef9a3fc7748992af8ac4e544ed0855"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"4c6785207b4216b2815068f68d438b3cbb6e480f684a661dc8f25d5e4b053e1b"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"5289188da20a1b4a9561cf814e0cc20dff38c1950d291892675948debc36a610"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"b4e6f8955890cf5188ed2227aebca561a2ff5e7b53e5d5363cdbb124b9b31702"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"96e80f91c323df150d08a477abe6697b287cd7a1b11e98d17cb15f682fa46012"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"2eb3dc85807c4889e72e18a82ebfe7ea6d43a114ed961a06f970a593a6785983"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"bc220bf4111305e7fcaf46756b531ac2aabc1d12c87f89184ba5f670b11229ab"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"b7a255452eb50e8b6cc3f3f589189d3c206c47395eed2aa6504d950ca7c69ea9"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"0d2d7067c8a8538fa40c6f0a68a666e65fa7a6f06f39de359e64ff30f752db5a"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"357cd413a37f173d51cacbdb6372d41b90b4d8d44787b6a2a456c7d4f4423336"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"7f21f53f2ba99894d65b3dee8518f9483805fc2bda9444939a5a1fa44d74df30"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"2585ca95ded13c334b95ab969054eb72353475b224a181fe710f7cb591ef939b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"b66856473b10327fc5c661d684b773ca0e4674821130a3072f198d498f56d8e6"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"d4282ddc4619978d0a0cf76e898d9495fc058935832a42fc8a7a14c56fa1566a"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"ac0af152fad9c3d01f36aaf003c8bee4cb2ea7fed022e612ce21bcfe7160a98b"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/routes.ts","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22291,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"01259043d1891028cd61f5f4f3f29041ed58295bd43e5d147d8d1f1daca037ce"},{"bytes":1498199,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"9de6133a4be254740f94b7adc0f127d1944af08699816b4f78d4c8b7465843dd"},{"bytes":2362069,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"2db5083337425e528943c4eec837d81ff079c787573e41fe3b4610adad63111b"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1418551,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"0607539fd2c35038761f036925a92fa656e27ac45acdb23721e64882fe04d556"},{"bytes":3245077,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"f34c137c230bcc7b07cbc039ac7ee522a35c649851051cd171b09aecb04de523"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1282057,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"956ee3ba0344d53f4bdaa2fa08fc30968dd1f90ec203088c4bf76507db537a31"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads; --host and --model-provider are separate filters.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter: all (default) | local | hostId or friendly name","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Pass-through to app-server modelProviders (omit = all)","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter: all (default) | local | hostId or friendly name","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Pass-through to app-server modelProviders (omit = all)","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads.","exitCode":"result","options":[{"description":"Opaque pagination cursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads; --host and --model-provider are separate filters.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads.","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"a7528652ca53097d55bc34f4cfa73b6315fd067ea572e7eda32112d0d9201e34","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"type":"string"},"limit":{"description":"Maximum threads in this page: 1-200.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"74f3207ba9cbfe8dbb1ad36e3617745c4adab85b6fd6202a400a21d800429160","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"be5ec043449dfaad125551d0ff185947b23943c670eba78823a6ff57767959f2","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"6a8b392ec45d4a5f70ce68fa35a285c2948c72d05671b07696b9ec9b0021cb89"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"1d3d8ed8ab8fe80184eb780262b5577cb26131a7b61b7e815737e9e412d8d4e6"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"1c03ed7644b8006a00b751ea3b97630e008e5896c3797ef0f1cb510b941c6234"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"6f9facafa101776ce7ddf4282a4f19edcfc40b76da251afa59f8e2f4350c9f33"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"21454ac9c648e0d130d40d1f15f9e909cf5c82eafa018e7a066a419b72cb0d41"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"8be4849f9c85c392d3e989d222d714169da982c0337d57cdc3411d14084d9bf3"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"583279e0360f529405948a6fb33712dabaa9917bb616bd00dcc83a6b6422827c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"8a45cab48d9f02da4fa2118e0a238696ab2f4ee198faff45ac64580c1f687d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"98edba7908cecffb141018bc358074f2785baf84bd76c4e9564843d48ad9e2dd"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"9b35df3fa9a4a1655b9cb2e2f0d3b83e796648fc8d4ab3cacfa856f78e6a2df5"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"e8e1ba9c8d39307cdd1d849fb1f8e93c7c90421fcaa5eb8bbfdf9b579241f1be"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"694159395711268403159676c679a6a0d939bbaff546b673136f0ce4a67d686a"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"f4843da5a5fde4728e2dfe6766be0ce29b50a45af8a9508df8fcf86dffaee651"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"8463e5a981dcc4f67b386c5f1b97504905ef9a3fc7748992af8ac4e544ed0855"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"5289188da20a1b4a9561cf814e0cc20dff38c1950d291892675948debc36a610"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"6f49f1cce9590831953915a8f1f8ecc3e641bc5a1230a26f35937f257393bc26"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"dfaf2ea60ea7e46be61accc91b20e591125618c83a1910ea20ed72a75322f9d8"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4d5f799e587d8d4be6e7bacb9209816c7756605f75a0595dc3d3052f04048624"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"b7a255452eb50e8b6cc3f3f589189d3c206c47395eed2aa6504d950ca7c69ea9"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"0d2d7067c8a8538fa40c6f0a68a666e65fa7a6f06f39de359e64ff30f752db5a"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"357cd413a37f173d51cacbdb6372d41b90b4d8d44787b6a2a456c7d4f4423336"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"7f21f53f2ba99894d65b3dee8518f9483805fc2bda9444939a5a1fa44d74df30"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"c473cd9f3954480e3280ad5ed8eef7b135571c94e0ff0a3b7f825348406b762c"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"ac0af152fad9c3d01f36aaf003c8bee4cb2ea7fed022e612ce21bcfe7160a98b"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22816,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"84afcff73e067dc324f28400ea06fb3a7477bbabe7c6234f0b80ad4a40f1ccb8"},{"bytes":1515489,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"59a193a8278b9fdd51fb47c4e02cc0c79c7a24fdf6d63bdaa3f44be8dcec23bf"},{"bytes":2379440,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"9be8afe780425204731648c4555d9918b36eca3cc6dc692d202d3682c505c432"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1436022,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"c2c85b5b9b1d9e3b6d6988fa4c53f60da14d44bd687ae4fc02303d22c3356c29"},{"bytes":3262537,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"9149f1cfbd0748efe8cf327f2902b9174d27891e53083739857a51c332c3668e"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298440,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads; --host and --model-provider are separate filters.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter: all (default) | local | hostId or friendly name","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Pass-through to app-server modelProviders (omit = all)","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter: all (default) | local | hostId or friendly name","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Pass-through to app-server modelProviders (omit = all)","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads; --host and --model-provider are separate filters.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"9081e7f6af0344bb36b13c6e652b65b524c34844a9eb2207db46d24d07a4a889","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index ebb8cb6..df87b8d 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -9505,13 +9505,13 @@ var __webpack_modules__ = { var _core_format_js__rspack_import_6 = __webpack_require__("./src/core/format.js"); var _shared_js__rspack_import_3 = __webpack_require__("./src/cli/_shared.ts"); const config = { - description: 'List Codex daemon-managed threads.', + description: 'List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).', exitCode: 'result', inputJsonSchema: { additionalProperties: false, properties: { cursor: { - description: 'Opaque pagination cursor (may start with -)', + description: 'Opaque pagination cursor from a previous nextCursor (may start with -)', type: 'string' }, limit: { @@ -9532,7 +9532,8 @@ var __webpack_modules__ = { exitCode: zod__rspack_import_4.euz(0), limit: zod__rspack_import_4.aig().int().min(1).max(200), nextCursor: zod__rspack_import_4.YjP().nullable(), - threads: zod__rspack_import_4.YOg(zod__rspack_import_4.g1P(zod__rspack_import_4.YjP(), zod__rspack_import_4.Pq9())) + threads: zod__rspack_import_4.YOg(zod__rspack_import_4.g1P(zod__rspack_import_4.YjP(), zod__rspack_import_4.Pq9())), + useStateDbOnly: zod__rspack_import_4.zMY().optional() }).strict(), _shared_js__rspack_import_3.R9 ]); @@ -12663,6 +12664,7 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); class NotImplementedError extends Error { code = 'NOT_IMPLEMENTED'; delivery = 'rejected'; @@ -12690,29 +12692,15 @@ var __webpack_modules__ = { this.name = 'CdpUnreachableError'; } } - class RemoteThreadNotLoadedError extends Error { - code = 'REMOTE_THREAD_NOT_LOADED'; - delivery = 'rejected'; - reason = 'remote-thread-not-loaded'; - threadId; - hostId; - hostName; - hint; + class RemoteThreadNotLoadedError1 extends _codex_remote_control_js__rspack_import_0.Rg { constructor(threadId, hostId = null, hostName = null){ - const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; - const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; - const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; - super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); + super(threadId, hostId, hostName); this.name = 'RemoteThreadNotLoadedError'; - this.threadId = threadId; - this.hostId = hostId; - this.hostName = hostName; - this.hint = hint; } } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, - Rg: ()=>RemoteThreadNotLoadedError, + Rg: ()=>RemoteThreadNotLoadedError1, c$: ()=>CdpHostRejectedError, sO: ()=>CdpUnreachableError }); @@ -12825,6 +12813,22 @@ var __webpack_modules__ = { ...host } ])); + for (const thread of remotes){ + const existing = byId.get(thread.hostId); + if (existing) { + byId.set(thread.hostId, { + ...existing, + hostName: existing.hostName ?? thread.hostName + }); + } else { + byId.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName, + location: 'remote', + threadCount: 0 + }); + } + } let hostsSource = 'remote-thread-summaries-v3+local'; try { const discoverEnvs = this.#fallbacks.discoverRemoteEnvironments ?? _app_server_fallback_js__rspack_import_1.OP; @@ -13954,19 +13958,21 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/thread-ids.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_thread_id_js__rspack_import_1 = __webpack_require__("./src/core/codex/thread-id.js"); var _cdp_dom_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); - const LOCAL_THREAD_ID_PREFIX = 'local:'; + const LOCAL_THREAD_ID_PREFIX = "local:"; + const TEMP_THREAD_ID_PREFIX = null && CDP_TEMP_PREFIX; const HISTORY_CONTENT_TURN_PREFIX = 'history-content:turn:'; function isTemporaryDesktopThreadId(threadId) { - return threadId.startsWith(_cdp_dom_js__rspack_import_0.hA); + return (0, _codex_thread_id_js__rspack_import_1.vr)(threadId) || threadId.startsWith(_codex_thread_id_js__rspack_import_1.hA); } function toAppServerThreadId(threadId) { if (!threadId || isTemporaryDesktopThreadId(threadId)) return null; - if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) { - const bare = threadId.slice(LOCAL_THREAD_ID_PREFIX.length); - return bare || null; + try { + return (0, _codex_thread_id_js__rspack_import_1.SX)(threadId); + } catch { + return null; } - return threadId; } function requireAppServerThreadId(threadId) { const bare = toAppServerThreadId(threadId); @@ -14051,10 +14057,23 @@ var __webpack_modules__ = { }, "./src/core/codex/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_3 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var zod__rspack_import_5 = __webpack_require__("./node_modules/zod/v4/core/core.js"); var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); var _contract_js__rspack_import_1 = __webpack_require__("./src/core/codex/contract.js"); var _conversation_js__rspack_import_2 = __webpack_require__("./src/core/codex/conversation.js"); - const id = zod__rspack_import_3.YjP().regex(/^[A-Za-z0-9_.:-]{1,128}$/); + var _thread_id_js__rspack_import_4 = __webpack_require__("./src/core/codex/thread-id.js"); + const bareId = zod__rspack_import_3.YjP().regex(/^[A-Za-z0-9_.:-]{1,128}$/); + const id = zod__rspack_import_3.YjP().min(1).max(160).transform((value, ctx)=>{ + try { + return (0, _thread_id_js__rspack_import_4.SX)(value); + } catch (error) { + ctx.addIssue({ + code: 'custom', + message: error instanceof Error ? error.message : 'Invalid threadId' + }); + return zod__rspack_import_5.tm; + } + }).pipe(bareId); const observationFields = { expectedCwd: zod__rspack_import_3.YjP().min(1).optional(), threadId: id, @@ -18404,11 +18423,12 @@ var __webpack_modules__ = { GT: ()=>$ZodAsyncError, cV: ()=>$ZodEncodeError, cr: ()=>globalConfig, + tm: ()=>NEVER, xI: ()=>$constructor }); var _util_js__rspack_import_0 = __webpack_require__("./node_modules/zod/v4/core/util.js"); var _a; - const NEVER = null && Object.freeze({ + const NEVER = Object.freeze({ status: "aborted" }); const _zodDesc = { @@ -24894,8 +24914,10 @@ var __webpack_modules__ = { var node_child_process__rspack_import_5 = __webpack_require__("node:child_process"); var _package_json__rspack_import_6 = __webpack_require__("./package.json"); var _codex_contract_js__rspack_import_7 = __webpack_require__("./src/core/codex/contract.js"); - var _desktop_shim_js__rspack_import_8 = __webpack_require__("./src/core/desktop-shim.js"); - var _user_machine_guidance_js__rspack_import_9 = __webpack_require__("./src/core/user-machine-guidance.js"); + var _codex_remote_control_js__rspack_import_8 = __webpack_require__("./src/core/codex/remote-control.js"); + var _codex_thread_id_js__rspack_import_11 = __webpack_require__("./src/core/codex/thread-id.js"); + var _desktop_shim_js__rspack_import_9 = __webpack_require__("./src/core/desktop-shim.js"); + var _user_machine_guidance_js__rspack_import_10 = __webpack_require__("./src/core/user-machine-guidance.js"); const PINNED_CODEX_VERSION = "0.154.0"; const UPSTREAM_DESKTOP_ISSUES = [ "https://github.com/openai/codex/issues/41014", @@ -24932,11 +24954,11 @@ var __webpack_modules__ = { function boxUnreachableMessage(path) { return [ "No Codex app-server control socket at " + path + ".", - _user_machine_guidance_js__rspack_import_9.M + _user_machine_guidance_js__rspack_import_10.M ].join("\n"); } function unreachableMessage(path, desktopAttached = "unknown", env = process.env) { - if ((0, _user_machine_guidance_js__rspack_import_9.R)({ + if ((0, _user_machine_guidance_js__rspack_import_10.R)({ path, env, home: env.HOME || (0, node_os__rspack_import_3.homedir)() @@ -25663,7 +25685,7 @@ var __webpack_modules__ = { let desktopShimConfigured = Boolean(shim && shim.installed && shim.wrapperPointsAtShim); if (shim === undefined) { try { - const live = (0, _desktop_shim_js__rspack_import_8.em)({ + const live = (0, _desktop_shim_js__rspack_import_9.em)({ env }); desktopShimConfigured = Boolean(live.installed && live.wrapperPointsAtShim); @@ -25772,33 +25794,52 @@ var __webpack_modules__ = { } const { client } = await openSession(env); try { - const params = { + const baseParams = { limit, - useStateDbOnly: true, modelProviders, ...cursor !== undefined ? { cursor } : {} }; let out; + let usedStateDbOnly = true; try { - out = await client.request("thread/list", params); + out = await client.request("thread/list", { + ...baseParams, + useStateDbOnly: true + }); } catch (err) { throw transportError(err); } if (!isObject(out) || !Array.isArray(out.data)) throw new CodexProtocolError("thread/list", "missing `data` array"); + if (out.data.length === 0 && cursor === undefined && (out.nextCursor == null || out.nextCursor === "")) { + try { + out = await client.request("thread/list", { + ...baseParams, + useStateDbOnly: false + }); + usedStateDbOnly = false; + } catch (err) { + throw transportError(err); + } + if (!isObject(out) || !Array.isArray(out.data)) throw new CodexProtocolError("thread/list", "missing `data` array"); + } if (out.nextCursor != null && typeof out.nextCursor !== "string") throw new CodexProtocolError("thread/list", "`nextCursor` is not a string"); const threads = out.data.map(summarizeThread); return { threads, nextCursor: out.nextCursor ?? null, - limit + limit, + useStateDbOnly: usedStateDbOnly }; } finally{ client.close(); } } - function explainSendError(err, threadId) { + function explainSendError(err, threadId, env = process.env) { + if (err instanceof _codex_remote_control_js__rspack_import_8.Rg) return err; + const mapped = (0, _codex_remote_control_js__rspack_import_8.R3)(err, threadId, env); + if (mapped instanceof _codex_remote_control_js__rspack_import_8.Rg) return mapped; if (!(err instanceof CodexRpcError)) return err; const msg = String(err.rpc && err.rpc.message || ""); if (/no rollout found|thread not found/i.test(msg)) { @@ -25873,12 +25914,19 @@ var __webpack_modules__ = { function assertThreadAllowed(threadId, env = process.env) { const raw = env.GROK_BOT_CODEX_THREADS; if (raw == null || raw.trim() === "") return; - const allowed = raw.split(",").map((s)=>s.trim()).filter(Boolean); - if (!allowed.includes(threadId)) { - throw new CodexSendError("Codex thread " + threadId + " is not in GROK_BOT_CODEX_THREADS; the operator allows only: " + allowed.join(", "), { + const bare = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); + const allowed = raw.split(",").map((s)=>{ + try { + return (0, _codex_thread_id_js__rspack_import_11.SX)(s.trim()); + } catch { + return s.trim(); + } + }).filter(Boolean); + if (!allowed.includes(bare)) { + throw new CodexSendError("Codex thread " + bare + " is not in GROK_BOT_CODEX_THREADS; the operator allows only: " + allowed.join(", "), { delivery: "rejected", reason: "route-not-allowed", - threadId + threadId: bare }); } } @@ -25948,6 +25996,7 @@ var __webpack_modules__ = { } async function listCodexQueue(threadId, { env = process.env, limit = 50, cursor } = {}) { requireExperimental(env, "gbot codex queue"); + threadId = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); const { client } = await openSession(env, { experimental: true }); @@ -25978,6 +26027,58 @@ var __webpack_modules__ = { client.close(); } } + async function readCodexThread(threadId, { limit = 100, env = process.env } = {}) { + if (!Number.isInteger(limit) || limit < 1 || limit > 2000) { + throw new RangeError("limit must be an integer 1-2000"); + } + const bare = normalizeCodexThreadId(threadId); + const { client } = await openSession(env); + try { + let meta; + try { + meta = await client.request("thread/read", { + threadId: bare + }); + } catch (err) { + const mapped = explainSendError(err, bare, env); + if (mapped instanceof RemoteThreadNotLoadedError) throw mapped; + throw transportError(err); + } + const turns = []; + let cursor; + for(let page = 0; page < 40 && turns.length < limit; page++){ + let out; + try { + out = await client.request("thread/turns/list", { + threadId: bare, + limit: Math.min(100, limit - turns.length), + itemsView: "full", + ...cursor !== undefined ? { + cursor + } : {} + }); + } catch (err) { + const mapped = explainSendError(err, bare, env); + if (mapped instanceof RemoteThreadNotLoadedError) throw mapped; + throw transportError(err); + } + if (!isObject(out) || !Array.isArray(out.data)) { + throw new CodexProtocolError("thread/turns/list", "missing `data` array"); + } + for (const row of out.data)turns.push(row); + if (out.nextCursor == null || typeof out.nextCursor !== "string") break; + cursor = out.nextCursor; + } + return { + threadId: bare, + thread: isObject(meta) && isObject(meta.thread) ? meta.thread : null, + turns: turns.slice(0, limit), + nextCursor: cursor ?? null + }; + } finally{ + client.close(); + } + } async function sendToCodexThread(threadId, text, { env = process.env, envelope = buildEnvelope({ env }), whenBusy = "reject", session, expectedTurnId, expectedCwd, signal } = {}) { @@ -26009,7 +26110,7 @@ var __webpack_modules__ = { ] : [] ].includes(whenBusy)) throw new RangeError("--when-busy must be reject, queue, or persistent steer"); if (whenBusy === "steer" && (typeof expectedTurnId !== "string" || !ID_PATTERN.test(expectedTurnId))) throw new RangeError("steer requires expectedTurnId"); - if (typeof threadId !== "string" || !ID_PATTERN.test(threadId)) throw new RangeError("Invalid threadId"); + threadId = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > WS_MAX_MESSAGE_BYTES) throw new RangeError("Message must contain text within 4 MiB"); if (!envelope || typeof envelope.messageId !== "string" || !ID_PATTERN.test(envelope.messageId)) throw new RangeError("Invalid envelope messageId"); const validated = buildEnvelope({ @@ -26050,8 +26151,10 @@ var __webpack_modules__ = { }); } catch (err) { assertNotCancelled(); - if (err instanceof CodexSendError) throw err; - throw new CodexSendError(explainSendError(err, threadId).message, { + if (err instanceof CodexSendError || err instanceof _codex_remote_control_js__rspack_import_8.Rg) throw err; + const explained = explainSendError(err, threadId, env); + if (explained instanceof _codex_remote_control_js__rspack_import_8.Rg) throw explained; + throw new CodexSendError(explained.message, { delivery: err instanceof CodexRpcError ? "rejected" : err && err.delivery || "unknown", reason: err instanceof CodexRpcError ? /no rollout found|thread not found/i.test(String(err.rpc && err.rpc.message)) ? "unknown-thread" : /active writer/i.test(String(err.rpc && err.rpc.message)) ? "external-owner" : "rejected" : "transport", threadId, @@ -26281,7 +26384,11 @@ var __webpack_modules__ = { "messageId", "correlationId", "refused", - "hop" + "hop", + "hostId", + "hostName", + "hint", + "code" ]){ if (error[key] !== undefined) out[key] = error[key]; } @@ -26317,9 +26424,12 @@ var __webpack_modules__ = { var _contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); var node_fs__rspack_import_1 = __webpack_require__("node:fs"); var _codex_bridge_js__rspack_import_2 = __webpack_require__("./src/core/codex-bridge.js"); + var _remote_control_js__rspack_import_3 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_id_js__rspack_import_4 = __webpack_require__("./src/core/codex/thread-id.js"); const ID = /^[A-Za-z0-9_.:-]{1,128}$/; const BUDGET = 4 * 1024 * 1024; function conversationId(value, name = 'threadId') { + if (name === 'threadId') return (0, _thread_id_js__rspack_import_4.SX)(value); if (typeof value !== 'string' || !ID.test(value)) throw new RangeError(`${name} must be 1-128 identifier characters`); return value; } @@ -26444,7 +26554,8 @@ var __webpack_modules__ = { if (expected !== undefined && (typeof cwd !== 'string' || (0, node_fs__rspack_import_1.realpathSync)(cwd) !== expected)) throw new Error('Codex thread cwd does not match expectedCwd'); } catch (error) { await close(); - throw error; + if (error instanceof _remote_control_js__rspack_import_3.Rg) throw error; + throw (0, _remote_control_js__rspack_import_3.R3)(error, threadId, env); } async function wait({ turnId, messageId, afterMessageId, timeoutMs = 120000, signal: waitSignal, maxOutputBytes = 1048576 }) { conversationId(turnId, 'turnId'); @@ -26750,6 +26861,263 @@ var __webpack_modules__ = { j: ()=>openCodexConversation }); }, + "./src/core/codex/remote-control.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var node_os__rspack_import_1 = __webpack_require__("node:os"); + var node_path__rspack_import_2 = __webpack_require__("node:path"); + var _thread_id_js__rspack_import_3 = __webpack_require__("./src/core/codex/thread-id.js"); + const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; + class RemoteThreadNotLoadedError1 extends Error { + constructor(threadId, hostId = null, hostName = null){ + const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; + const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); + this.name = 'RemoteThreadNotLoadedError'; + this.code = 'REMOTE_THREAD_NOT_LOADED'; + this.delivery = 'rejected'; + this.reason = 'remote-thread-not-loaded'; + this.threadId = threadId; + this.hostId = hostId; + this.hostName = hostName; + this.hint = hint; + } + } + function codexGlobalStatePath(env = process.env) { + const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); + return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); + } + function loadCodexGlobalState(env = process.env) { + let raw; + try { + raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); + } catch { + return null; + } + try { + const data = JSON.parse(raw); + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + return data; + } catch { + return null; + } + } + function findRemoteThreadHost(threadId, env = process.env) { + let bare; + try { + bare = (0, _thread_id_js__rspack_import_3.SX)(threadId); + } catch { + bare = typeof threadId === 'string' && threadId.startsWith("local:") ? threadId.slice("local:".length) : threadId; + } + if (!bare) return null; + const data = loadCodexGlobalState(env); + if (!data) return null; + const hostNames = collectHostNames(data); + for (const [key, value] of Object.entries(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match?.[1]) continue; + const hostId = match[1]; + const hostName = hostNames.get(hostId) ?? extractHostName(value) ?? null; + for (const entry of extractThreadEntries(value)){ + const id = threadIdFromEntry(entry); + if (!id) continue; + const entryBare = id.startsWith("local:") ? id.slice("local:".length) : id; + if (entryBare === bare) return { + hostId, + hostName + }; + } + } + return null; + } + function mapRemoteThreadError(error, threadId, env = process.env) { + const message = errorMessage(error); + if (!/thread not loaded|not loaded|no rollout found|thread not found|invalid thread id/i.test(message)) { + return error instanceof Error ? error : new Error(message || String(error)); + } + const remote = findRemoteThreadHost(threadId, env); + if (remote) { + return new RemoteThreadNotLoadedError1(threadId, remote.hostId, remote.hostName); + } + if (/thread not loaded|not loaded/i.test(message)) { + return new RemoteThreadNotLoadedError1(threadId, null, null); + } + return error instanceof Error ? error : new Error(message || String(error)); + } + function collectHostNames(data) { + const names = new Map(); + for (const [key, value] of Object.entries(data)){ + if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; + if (!value || typeof value !== 'object') continue; + if (Array.isArray(value)) { + for (const entry of value){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + continue; + } + for (const [hostId, entry] of Object.entries(value)){ + const fromEntry = hostNameFromEntry(entry); + if (fromEntry) { + names.set(fromEntry.hostId, fromEntry.hostName); + continue; + } + const label = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (label) names.set(hostId, label); + } + } + return names; + } + function hostNameFromEntry(entry) { + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + const hostId = stringField(entry, [ + 'hostId', + 'id', + 'host_id', + 'uuid' + ]); + const hostName = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (!hostId || !hostName) return null; + return { + hostId, + hostName + }; + } + function extractHostName(value) { + if (!value || typeof value !== 'object' || Array.isArray(value)) return null; + return stringField(value, [ + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName' + ]); + } + function extractThreadEntries(value) { + if (Array.isArray(value)) return value; + if (!value || typeof value !== 'object') return []; + const record = value; + for (const key of [ + 'threads', + 'summaries', + 'items', + 'data', + 'conversations' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + const entries = []; + for (const [key, entry] of Object.entries(record)){ + if ([ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName', + 'hostId', + 'version' + ].includes(key)) continue; + if (typeof entry === 'string') continue; + if (entry && typeof entry === 'object' && !Array.isArray(entry)) { + const id = stringField(entry, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]); + entries.push(id ? entry : { + ...entry, + id: key + }); + } + } + return entries; + } + function threadIdFromEntry(entry) { + if (typeof entry === 'string' && entry) return entry; + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + return stringField(entry, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]); + } + function stringField(row, keys) { + if (!row || typeof row !== 'object' || Array.isArray(row)) return null; + for (const key of keys){ + const value = row[key]; + if (typeof value === 'string' && value.trim()) return value.trim(); + } + return null; + } + function errorMessage(error) { + if (!error) return ''; + if (typeof error === 'string') return error; + if (error instanceof Error) return error.message; + if (typeof error === 'object' && error && 'message' in error) return String(error.message); + if (typeof error === 'object' && error && 'rpc' in error) { + const rpc = error.rpc; + if (rpc && typeof rpc.message === 'string') return rpc.message; + } + return String(error); + } + __webpack_require__.d(__webpack_exports__, { + R3: ()=>mapRemoteThreadError, + Rg: ()=>RemoteThreadNotLoadedError1 + }); + }, + "./src/core/codex/thread-id.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { + const LOCAL_THREAD_ID_PREFIX = 'local:'; + const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; + const ID_PATTERN = /^[A-Za-z0-9_.:-]{1,128}$/; + function isTemporaryDesktopThreadId(threadId) { + return typeof threadId === 'string' && threadId.startsWith(TEMP_THREAD_ID_PREFIX); + } + function normalizeCodexThreadId1(threadId) { + if (typeof threadId !== 'string' || !threadId) { + throw new RangeError('Invalid threadId'); + } + if (isTemporaryDesktopThreadId(threadId)) { + throw new RangeError('Temporary Desktop thread id ' + JSON.stringify(threadId) + ' has no app-server mapping; wait for the real conversation id'); + } + const bare = threadId.startsWith(LOCAL_THREAD_ID_PREFIX) ? threadId.slice(LOCAL_THREAD_ID_PREFIX.length) : threadId; + if (!bare || !ID_PATTERN.test(bare)) { + throw new RangeError('Invalid threadId'); + } + return bare; + } + function hasLocalThreadPrefix(threadId) { + return typeof threadId === 'string' && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) && !isTemporaryDesktopThreadId(threadId); + } + __webpack_require__.d(__webpack_exports__, { + SX: ()=>normalizeCodexThreadId1, + vr: ()=>isTemporaryDesktopThreadId + }, { + hA: TEMP_THREAD_ID_PREFIX + }); + }, "./src/core/commands.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { var _store_js__rspack_import_0 = __webpack_require__("./src/core/store.js"); var _gateway_js__rspack_import_1 = __webpack_require__("./src/core/gateway.js"); diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index 75dd558..8a8440a 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -7913,13 +7913,13 @@ var __webpack_modules__ = { var _core_format_js__rspack_import_6 = __webpack_require__("./src/core/format.js"); var _shared_js__rspack_import_3 = __webpack_require__("./src/cli/_shared.ts"); const config = { - description: 'List Codex daemon-managed threads.', + description: 'List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).', exitCode: 'result', inputJsonSchema: { additionalProperties: false, properties: { cursor: { - description: 'Opaque pagination cursor (may start with -)', + description: 'Opaque pagination cursor from a previous nextCursor (may start with -)', type: 'string' }, limit: { @@ -7940,7 +7940,8 @@ var __webpack_modules__ = { exitCode: zod__rspack_import_4.euz(0), limit: zod__rspack_import_4.aig().int().min(1).max(200), nextCursor: zod__rspack_import_4.YjP().nullable(), - threads: zod__rspack_import_4.YOg(zod__rspack_import_4.g1P(zod__rspack_import_4.YjP(), zod__rspack_import_4.Pq9())) + threads: zod__rspack_import_4.YOg(zod__rspack_import_4.g1P(zod__rspack_import_4.YjP(), zod__rspack_import_4.Pq9())), + useStateDbOnly: zod__rspack_import_4.zMY().optional() }).strict(), _shared_js__rspack_import_3.R9 ]); @@ -11071,6 +11072,7 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); class NotImplementedError extends Error { code = 'NOT_IMPLEMENTED'; delivery = 'rejected'; @@ -11098,29 +11100,15 @@ var __webpack_modules__ = { this.name = 'CdpUnreachableError'; } } - class RemoteThreadNotLoadedError extends Error { - code = 'REMOTE_THREAD_NOT_LOADED'; - delivery = 'rejected'; - reason = 'remote-thread-not-loaded'; - threadId; - hostId; - hostName; - hint; + class RemoteThreadNotLoadedError1 extends _codex_remote_control_js__rspack_import_0.Rg { constructor(threadId, hostId = null, hostName = null){ - const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; - const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; - const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; - super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); + super(threadId, hostId, hostName); this.name = 'RemoteThreadNotLoadedError'; - this.threadId = threadId; - this.hostId = hostId; - this.hostName = hostName; - this.hint = hint; } } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, - Rg: ()=>RemoteThreadNotLoadedError, + Rg: ()=>RemoteThreadNotLoadedError1, c$: ()=>CdpHostRejectedError, sO: ()=>CdpUnreachableError }); @@ -11233,6 +11221,22 @@ var __webpack_modules__ = { ...host } ])); + for (const thread of remotes){ + const existing = byId.get(thread.hostId); + if (existing) { + byId.set(thread.hostId, { + ...existing, + hostName: existing.hostName ?? thread.hostName + }); + } else { + byId.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName, + location: 'remote', + threadCount: 0 + }); + } + } let hostsSource = 'remote-thread-summaries-v3+local'; try { const discoverEnvs = this.#fallbacks.discoverRemoteEnvironments ?? _app_server_fallback_js__rspack_import_1.OP; @@ -12362,19 +12366,21 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/thread-ids.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_thread_id_js__rspack_import_1 = __webpack_require__("./src/core/codex/thread-id.js"); var _cdp_dom_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); - const LOCAL_THREAD_ID_PREFIX = 'local:'; + const LOCAL_THREAD_ID_PREFIX = "local:"; + const TEMP_THREAD_ID_PREFIX = null && CDP_TEMP_PREFIX; const HISTORY_CONTENT_TURN_PREFIX = 'history-content:turn:'; function isTemporaryDesktopThreadId(threadId) { - return threadId.startsWith(_cdp_dom_js__rspack_import_0.hA); + return (0, _codex_thread_id_js__rspack_import_1.vr)(threadId) || threadId.startsWith(_codex_thread_id_js__rspack_import_1.hA); } function toAppServerThreadId(threadId) { if (!threadId || isTemporaryDesktopThreadId(threadId)) return null; - if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) { - const bare = threadId.slice(LOCAL_THREAD_ID_PREFIX.length); - return bare || null; + try { + return (0, _codex_thread_id_js__rspack_import_1.SX)(threadId); + } catch { + return null; } - return threadId; } function requireAppServerThreadId(threadId) { const bare = toAppServerThreadId(threadId); @@ -12459,10 +12465,23 @@ var __webpack_modules__ = { }, "./src/core/codex/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_3 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var zod__rspack_import_5 = __webpack_require__("./node_modules/zod/v4/core/core.js"); var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); var _contract_js__rspack_import_1 = __webpack_require__("./src/core/codex/contract.js"); var _conversation_js__rspack_import_2 = __webpack_require__("./src/core/codex/conversation.js"); - const id = zod__rspack_import_3.YjP().regex(/^[A-Za-z0-9_.:-]{1,128}$/); + var _thread_id_js__rspack_import_4 = __webpack_require__("./src/core/codex/thread-id.js"); + const bareId = zod__rspack_import_3.YjP().regex(/^[A-Za-z0-9_.:-]{1,128}$/); + const id = zod__rspack_import_3.YjP().min(1).max(160).transform((value, ctx)=>{ + try { + return (0, _thread_id_js__rspack_import_4.SX)(value); + } catch (error) { + ctx.addIssue({ + code: 'custom', + message: error instanceof Error ? error.message : 'Invalid threadId' + }); + return zod__rspack_import_5.tm; + } + }).pipe(bareId); const observationFields = { expectedCwd: zod__rspack_import_3.YjP().min(1).optional(), threadId: id, @@ -33977,11 +33996,12 @@ var __webpack_modules__ = { GT: ()=>$ZodAsyncError, cV: ()=>$ZodEncodeError, cr: ()=>globalConfig, + tm: ()=>NEVER, xI: ()=>$constructor }); var _util_js__rspack_import_0 = __webpack_require__("./node_modules/zod/v4/core/util.js"); var _a; - const NEVER = null && Object.freeze({ + const NEVER = Object.freeze({ status: "aborted" }); const _zodDesc = { @@ -41198,11 +41218,11 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "List Codex daemon-managed threads.", + "description": "List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).", "exitCode": "result", "options": [ { - "description": "Opaque pagination cursor (may start with -)", + "description": "Opaque pagination cursor from a previous nextCursor (may start with -)", "key": "cursor", "kind": "string", "option": "cursor", @@ -43109,8 +43129,10 @@ var __webpack_modules__ = { var node_child_process__rspack_import_5 = __webpack_require__("node:child_process"); var _package_json__rspack_import_6 = __webpack_require__("./package.json"); var _codex_contract_js__rspack_import_7 = __webpack_require__("./src/core/codex/contract.js"); - var _desktop_shim_js__rspack_import_8 = __webpack_require__("./src/core/desktop-shim.js"); - var _user_machine_guidance_js__rspack_import_9 = __webpack_require__("./src/core/user-machine-guidance.js"); + var _codex_remote_control_js__rspack_import_8 = __webpack_require__("./src/core/codex/remote-control.js"); + var _codex_thread_id_js__rspack_import_11 = __webpack_require__("./src/core/codex/thread-id.js"); + var _desktop_shim_js__rspack_import_9 = __webpack_require__("./src/core/desktop-shim.js"); + var _user_machine_guidance_js__rspack_import_10 = __webpack_require__("./src/core/user-machine-guidance.js"); const PINNED_CODEX_VERSION = "0.154.0"; const UPSTREAM_DESKTOP_ISSUES = [ "https://github.com/openai/codex/issues/41014", @@ -43147,11 +43169,11 @@ var __webpack_modules__ = { function boxUnreachableMessage(path) { return [ "No Codex app-server control socket at " + path + ".", - _user_machine_guidance_js__rspack_import_9.M + _user_machine_guidance_js__rspack_import_10.M ].join("\n"); } function unreachableMessage(path, desktopAttached = "unknown", env = process.env) { - if ((0, _user_machine_guidance_js__rspack_import_9.R)({ + if ((0, _user_machine_guidance_js__rspack_import_10.R)({ path, env, home: env.HOME || (0, node_os__rspack_import_3.homedir)() @@ -43878,7 +43900,7 @@ var __webpack_modules__ = { let desktopShimConfigured = Boolean(shim && shim.installed && shim.wrapperPointsAtShim); if (shim === undefined) { try { - const live = (0, _desktop_shim_js__rspack_import_8.em)({ + const live = (0, _desktop_shim_js__rspack_import_9.em)({ env }); desktopShimConfigured = Boolean(live.installed && live.wrapperPointsAtShim); @@ -43987,33 +44009,52 @@ var __webpack_modules__ = { } const { client } = await openSession(env); try { - const params = { + const baseParams = { limit, - useStateDbOnly: true, modelProviders, ...cursor !== undefined ? { cursor } : {} }; let out; + let usedStateDbOnly = true; try { - out = await client.request("thread/list", params); + out = await client.request("thread/list", { + ...baseParams, + useStateDbOnly: true + }); } catch (err) { throw transportError(err); } if (!isObject(out) || !Array.isArray(out.data)) throw new CodexProtocolError("thread/list", "missing `data` array"); + if (out.data.length === 0 && cursor === undefined && (out.nextCursor == null || out.nextCursor === "")) { + try { + out = await client.request("thread/list", { + ...baseParams, + useStateDbOnly: false + }); + usedStateDbOnly = false; + } catch (err) { + throw transportError(err); + } + if (!isObject(out) || !Array.isArray(out.data)) throw new CodexProtocolError("thread/list", "missing `data` array"); + } if (out.nextCursor != null && typeof out.nextCursor !== "string") throw new CodexProtocolError("thread/list", "`nextCursor` is not a string"); const threads = out.data.map(summarizeThread); return { threads, nextCursor: out.nextCursor ?? null, - limit + limit, + useStateDbOnly: usedStateDbOnly }; } finally{ client.close(); } } - function explainSendError(err, threadId) { + function explainSendError(err, threadId, env = process.env) { + if (err instanceof _codex_remote_control_js__rspack_import_8.Rg) return err; + const mapped = (0, _codex_remote_control_js__rspack_import_8.R3)(err, threadId, env); + if (mapped instanceof _codex_remote_control_js__rspack_import_8.Rg) return mapped; if (!(err instanceof CodexRpcError)) return err; const msg = String(err.rpc && err.rpc.message || ""); if (/no rollout found|thread not found/i.test(msg)) { @@ -44088,12 +44129,19 @@ var __webpack_modules__ = { function assertThreadAllowed(threadId, env = process.env) { const raw = env.GROK_BOT_CODEX_THREADS; if (raw == null || raw.trim() === "") return; - const allowed = raw.split(",").map((s)=>s.trim()).filter(Boolean); - if (!allowed.includes(threadId)) { - throw new CodexSendError("Codex thread " + threadId + " is not in GROK_BOT_CODEX_THREADS; the operator allows only: " + allowed.join(", "), { + const bare = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); + const allowed = raw.split(",").map((s)=>{ + try { + return (0, _codex_thread_id_js__rspack_import_11.SX)(s.trim()); + } catch { + return s.trim(); + } + }).filter(Boolean); + if (!allowed.includes(bare)) { + throw new CodexSendError("Codex thread " + bare + " is not in GROK_BOT_CODEX_THREADS; the operator allows only: " + allowed.join(", "), { delivery: "rejected", reason: "route-not-allowed", - threadId + threadId: bare }); } } @@ -44163,6 +44211,7 @@ var __webpack_modules__ = { } async function listCodexQueue(threadId, { env = process.env, limit = 50, cursor } = {}) { requireExperimental(env, "gbot codex queue"); + threadId = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); const { client } = await openSession(env, { experimental: true }); @@ -44193,6 +44242,58 @@ var __webpack_modules__ = { client.close(); } } + async function readCodexThread(threadId, { limit = 100, env = process.env } = {}) { + if (!Number.isInteger(limit) || limit < 1 || limit > 2000) { + throw new RangeError("limit must be an integer 1-2000"); + } + const bare = normalizeCodexThreadId(threadId); + const { client } = await openSession(env); + try { + let meta; + try { + meta = await client.request("thread/read", { + threadId: bare + }); + } catch (err) { + const mapped = explainSendError(err, bare, env); + if (mapped instanceof RemoteThreadNotLoadedError) throw mapped; + throw transportError(err); + } + const turns = []; + let cursor; + for(let page = 0; page < 40 && turns.length < limit; page++){ + let out; + try { + out = await client.request("thread/turns/list", { + threadId: bare, + limit: Math.min(100, limit - turns.length), + itemsView: "full", + ...cursor !== undefined ? { + cursor + } : {} + }); + } catch (err) { + const mapped = explainSendError(err, bare, env); + if (mapped instanceof RemoteThreadNotLoadedError) throw mapped; + throw transportError(err); + } + if (!isObject(out) || !Array.isArray(out.data)) { + throw new CodexProtocolError("thread/turns/list", "missing `data` array"); + } + for (const row of out.data)turns.push(row); + if (out.nextCursor == null || typeof out.nextCursor !== "string") break; + cursor = out.nextCursor; + } + return { + threadId: bare, + thread: isObject(meta) && isObject(meta.thread) ? meta.thread : null, + turns: turns.slice(0, limit), + nextCursor: cursor ?? null + }; + } finally{ + client.close(); + } + } async function sendToCodexThread(threadId, text, { env = process.env, envelope = buildEnvelope({ env }), whenBusy = "reject", session, expectedTurnId, expectedCwd, signal } = {}) { @@ -44224,7 +44325,7 @@ var __webpack_modules__ = { ] : [] ].includes(whenBusy)) throw new RangeError("--when-busy must be reject, queue, or persistent steer"); if (whenBusy === "steer" && (typeof expectedTurnId !== "string" || !ID_PATTERN.test(expectedTurnId))) throw new RangeError("steer requires expectedTurnId"); - if (typeof threadId !== "string" || !ID_PATTERN.test(threadId)) throw new RangeError("Invalid threadId"); + threadId = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > WS_MAX_MESSAGE_BYTES) throw new RangeError("Message must contain text within 4 MiB"); if (!envelope || typeof envelope.messageId !== "string" || !ID_PATTERN.test(envelope.messageId)) throw new RangeError("Invalid envelope messageId"); const validated = buildEnvelope({ @@ -44265,8 +44366,10 @@ var __webpack_modules__ = { }); } catch (err) { assertNotCancelled(); - if (err instanceof CodexSendError) throw err; - throw new CodexSendError(explainSendError(err, threadId).message, { + if (err instanceof CodexSendError || err instanceof _codex_remote_control_js__rspack_import_8.Rg) throw err; + const explained = explainSendError(err, threadId, env); + if (explained instanceof _codex_remote_control_js__rspack_import_8.Rg) throw explained; + throw new CodexSendError(explained.message, { delivery: err instanceof CodexRpcError ? "rejected" : err && err.delivery || "unknown", reason: err instanceof CodexRpcError ? /no rollout found|thread not found/i.test(String(err.rpc && err.rpc.message)) ? "unknown-thread" : /active writer/i.test(String(err.rpc && err.rpc.message)) ? "external-owner" : "rejected" : "transport", threadId, @@ -44496,7 +44599,11 @@ var __webpack_modules__ = { "messageId", "correlationId", "refused", - "hop" + "hop", + "hostId", + "hostName", + "hint", + "code" ]){ if (error[key] !== undefined) out[key] = error[key]; } @@ -44532,9 +44639,12 @@ var __webpack_modules__ = { var _contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); var node_fs__rspack_import_1 = __webpack_require__("node:fs"); var _codex_bridge_js__rspack_import_2 = __webpack_require__("./src/core/codex-bridge.js"); + var _remote_control_js__rspack_import_3 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_id_js__rspack_import_4 = __webpack_require__("./src/core/codex/thread-id.js"); const ID = /^[A-Za-z0-9_.:-]{1,128}$/; const BUDGET = 4 * 1024 * 1024; function conversationId(value, name = 'threadId') { + if (name === 'threadId') return (0, _thread_id_js__rspack_import_4.SX)(value); if (typeof value !== 'string' || !ID.test(value)) throw new RangeError(`${name} must be 1-128 identifier characters`); return value; } @@ -44659,7 +44769,8 @@ var __webpack_modules__ = { if (expected !== undefined && (typeof cwd !== 'string' || (0, node_fs__rspack_import_1.realpathSync)(cwd) !== expected)) throw new Error('Codex thread cwd does not match expectedCwd'); } catch (error) { await close(); - throw error; + if (error instanceof _remote_control_js__rspack_import_3.Rg) throw error; + throw (0, _remote_control_js__rspack_import_3.R3)(error, threadId, env); } async function wait({ turnId, messageId, afterMessageId, timeoutMs = 120000, signal: waitSignal, maxOutputBytes = 1048576 }) { conversationId(turnId, 'turnId'); @@ -44965,6 +45076,263 @@ var __webpack_modules__ = { j: ()=>openCodexConversation }); }, + "./src/core/codex/remote-control.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var node_os__rspack_import_1 = __webpack_require__("node:os"); + var node_path__rspack_import_2 = __webpack_require__("node:path"); + var _thread_id_js__rspack_import_3 = __webpack_require__("./src/core/codex/thread-id.js"); + const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; + class RemoteThreadNotLoadedError1 extends Error { + constructor(threadId, hostId = null, hostName = null){ + const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; + const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); + this.name = 'RemoteThreadNotLoadedError'; + this.code = 'REMOTE_THREAD_NOT_LOADED'; + this.delivery = 'rejected'; + this.reason = 'remote-thread-not-loaded'; + this.threadId = threadId; + this.hostId = hostId; + this.hostName = hostName; + this.hint = hint; + } + } + function codexGlobalStatePath(env = process.env) { + const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); + return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); + } + function loadCodexGlobalState(env = process.env) { + let raw; + try { + raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); + } catch { + return null; + } + try { + const data = JSON.parse(raw); + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + return data; + } catch { + return null; + } + } + function findRemoteThreadHost(threadId, env = process.env) { + let bare; + try { + bare = (0, _thread_id_js__rspack_import_3.SX)(threadId); + } catch { + bare = typeof threadId === 'string' && threadId.startsWith("local:") ? threadId.slice("local:".length) : threadId; + } + if (!bare) return null; + const data = loadCodexGlobalState(env); + if (!data) return null; + const hostNames = collectHostNames(data); + for (const [key, value] of Object.entries(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match?.[1]) continue; + const hostId = match[1]; + const hostName = hostNames.get(hostId) ?? extractHostName(value) ?? null; + for (const entry of extractThreadEntries(value)){ + const id = threadIdFromEntry(entry); + if (!id) continue; + const entryBare = id.startsWith("local:") ? id.slice("local:".length) : id; + if (entryBare === bare) return { + hostId, + hostName + }; + } + } + return null; + } + function mapRemoteThreadError(error, threadId, env = process.env) { + const message = errorMessage(error); + if (!/thread not loaded|not loaded|no rollout found|thread not found|invalid thread id/i.test(message)) { + return error instanceof Error ? error : new Error(message || String(error)); + } + const remote = findRemoteThreadHost(threadId, env); + if (remote) { + return new RemoteThreadNotLoadedError1(threadId, remote.hostId, remote.hostName); + } + if (/thread not loaded|not loaded/i.test(message)) { + return new RemoteThreadNotLoadedError1(threadId, null, null); + } + return error instanceof Error ? error : new Error(message || String(error)); + } + function collectHostNames(data) { + const names = new Map(); + for (const [key, value] of Object.entries(data)){ + if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; + if (!value || typeof value !== 'object') continue; + if (Array.isArray(value)) { + for (const entry of value){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + continue; + } + for (const [hostId, entry] of Object.entries(value)){ + const fromEntry = hostNameFromEntry(entry); + if (fromEntry) { + names.set(fromEntry.hostId, fromEntry.hostName); + continue; + } + const label = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (label) names.set(hostId, label); + } + } + return names; + } + function hostNameFromEntry(entry) { + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + const hostId = stringField(entry, [ + 'hostId', + 'id', + 'host_id', + 'uuid' + ]); + const hostName = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (!hostId || !hostName) return null; + return { + hostId, + hostName + }; + } + function extractHostName(value) { + if (!value || typeof value !== 'object' || Array.isArray(value)) return null; + return stringField(value, [ + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName' + ]); + } + function extractThreadEntries(value) { + if (Array.isArray(value)) return value; + if (!value || typeof value !== 'object') return []; + const record = value; + for (const key of [ + 'threads', + 'summaries', + 'items', + 'data', + 'conversations' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + const entries = []; + for (const [key, entry] of Object.entries(record)){ + if ([ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName', + 'hostId', + 'version' + ].includes(key)) continue; + if (typeof entry === 'string') continue; + if (entry && typeof entry === 'object' && !Array.isArray(entry)) { + const id = stringField(entry, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]); + entries.push(id ? entry : { + ...entry, + id: key + }); + } + } + return entries; + } + function threadIdFromEntry(entry) { + if (typeof entry === 'string' && entry) return entry; + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + return stringField(entry, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]); + } + function stringField(row, keys) { + if (!row || typeof row !== 'object' || Array.isArray(row)) return null; + for (const key of keys){ + const value = row[key]; + if (typeof value === 'string' && value.trim()) return value.trim(); + } + return null; + } + function errorMessage(error) { + if (!error) return ''; + if (typeof error === 'string') return error; + if (error instanceof Error) return error.message; + if (typeof error === 'object' && error && 'message' in error) return String(error.message); + if (typeof error === 'object' && error && 'rpc' in error) { + const rpc = error.rpc; + if (rpc && typeof rpc.message === 'string') return rpc.message; + } + return String(error); + } + __webpack_require__.d(__webpack_exports__, { + R3: ()=>mapRemoteThreadError, + Rg: ()=>RemoteThreadNotLoadedError1 + }); + }, + "./src/core/codex/thread-id.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { + const LOCAL_THREAD_ID_PREFIX = 'local:'; + const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; + const ID_PATTERN = /^[A-Za-z0-9_.:-]{1,128}$/; + function isTemporaryDesktopThreadId(threadId) { + return typeof threadId === 'string' && threadId.startsWith(TEMP_THREAD_ID_PREFIX); + } + function normalizeCodexThreadId1(threadId) { + if (typeof threadId !== 'string' || !threadId) { + throw new RangeError('Invalid threadId'); + } + if (isTemporaryDesktopThreadId(threadId)) { + throw new RangeError('Temporary Desktop thread id ' + JSON.stringify(threadId) + ' has no app-server mapping; wait for the real conversation id'); + } + const bare = threadId.startsWith(LOCAL_THREAD_ID_PREFIX) ? threadId.slice(LOCAL_THREAD_ID_PREFIX.length) : threadId; + if (!bare || !ID_PATTERN.test(bare)) { + throw new RangeError('Invalid threadId'); + } + return bare; + } + function hasLocalThreadPrefix(threadId) { + return typeof threadId === 'string' && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) && !isTemporaryDesktopThreadId(threadId); + } + __webpack_require__.d(__webpack_exports__, { + SX: ()=>normalizeCodexThreadId1, + vr: ()=>isTemporaryDesktopThreadId + }, { + hA: TEMP_THREAD_ID_PREFIX + }); + }, "./src/core/commands.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { var _store_js__rspack_import_0 = __webpack_require__("./src/core/store.js"); var _gateway_js__rspack_import_1 = __webpack_require__("./src/core/gateway.js"); diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index 9b3a4fd..e3dcf99 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -9479,6 +9479,7 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); class NotImplementedError extends Error { code = 'NOT_IMPLEMENTED'; delivery = 'rejected'; @@ -9506,29 +9507,15 @@ var __webpack_modules__ = { this.name = 'CdpUnreachableError'; } } - class RemoteThreadNotLoadedError extends Error { - code = 'REMOTE_THREAD_NOT_LOADED'; - delivery = 'rejected'; - reason = 'remote-thread-not-loaded'; - threadId; - hostId; - hostName; - hint; + class RemoteThreadNotLoadedError1 extends _codex_remote_control_js__rspack_import_0.Rg { constructor(threadId, hostId = null, hostName = null){ - const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; - const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; - const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; - super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); + super(threadId, hostId, hostName); this.name = 'RemoteThreadNotLoadedError'; - this.threadId = threadId; - this.hostId = hostId; - this.hostName = hostName; - this.hint = hint; } } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, - Rg: ()=>RemoteThreadNotLoadedError, + Rg: ()=>RemoteThreadNotLoadedError1, c$: ()=>CdpHostRejectedError, sO: ()=>CdpUnreachableError }); @@ -9641,6 +9628,22 @@ var __webpack_modules__ = { ...host } ])); + for (const thread of remotes){ + const existing = byId.get(thread.hostId); + if (existing) { + byId.set(thread.hostId, { + ...existing, + hostName: existing.hostName ?? thread.hostName + }); + } else { + byId.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName, + location: 'remote', + threadCount: 0 + }); + } + } let hostsSource = 'remote-thread-summaries-v3+local'; try { const discoverEnvs = this.#fallbacks.discoverRemoteEnvironments ?? _app_server_fallback_js__rspack_import_1.OP; @@ -10778,19 +10781,21 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/thread-ids.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_thread_id_js__rspack_import_1 = __webpack_require__("./src/core/codex/thread-id.js"); var _cdp_dom_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); - const LOCAL_THREAD_ID_PREFIX = 'local:'; + const LOCAL_THREAD_ID_PREFIX = "local:"; + const TEMP_THREAD_ID_PREFIX = null && CDP_TEMP_PREFIX; const HISTORY_CONTENT_TURN_PREFIX = 'history-content:turn:'; function isTemporaryDesktopThreadId(threadId) { - return threadId.startsWith(_cdp_dom_js__rspack_import_0.hA); + return (0, _codex_thread_id_js__rspack_import_1.vr)(threadId) || threadId.startsWith(_codex_thread_id_js__rspack_import_1.hA); } function toAppServerThreadId(threadId) { if (!threadId || isTemporaryDesktopThreadId(threadId)) return null; - if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) { - const bare = threadId.slice(LOCAL_THREAD_ID_PREFIX.length); - return bare || null; + try { + return (0, _codex_thread_id_js__rspack_import_1.SX)(threadId); + } catch { + return null; } - return threadId; } function requireAppServerThreadId(threadId) { const bare = toAppServerThreadId(threadId); @@ -10875,10 +10880,23 @@ var __webpack_modules__ = { }, "./src/core/codex/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_3 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var zod__rspack_import_5 = __webpack_require__("./node_modules/zod/v4/core/core.js"); var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); var _contract_js__rspack_import_1 = __webpack_require__("./src/core/codex/contract.js"); var _conversation_js__rspack_import_2 = __webpack_require__("./src/core/codex/conversation.js"); - const id = zod__rspack_import_3.YjP().regex(/^[A-Za-z0-9_.:-]{1,128}$/); + var _thread_id_js__rspack_import_4 = __webpack_require__("./src/core/codex/thread-id.js"); + const bareId = zod__rspack_import_3.YjP().regex(/^[A-Za-z0-9_.:-]{1,128}$/); + const id = zod__rspack_import_3.YjP().min(1).max(160).transform((value, ctx)=>{ + try { + return (0, _thread_id_js__rspack_import_4.SX)(value); + } catch (error) { + ctx.addIssue({ + code: 'custom', + message: error instanceof Error ? error.message : 'Invalid threadId' + }); + return zod__rspack_import_5.tm; + } + }).pipe(bareId); const observationFields = { expectedCwd: zod__rspack_import_3.YjP().min(1).optional(), threadId: id, @@ -11962,10 +11980,11 @@ var __webpack_modules__ = { properties: { "limit": { "type": "number", - "description": "Maximum threads in this page: 1-200." + "description": "Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page." }, "cursor": { - "type": "string" + "type": "string", + "description": "Opaque nextCursor from a previous page." } }, required: [] @@ -17077,11 +17096,12 @@ var __webpack_modules__ = { GT: ()=>$ZodAsyncError, cV: ()=>$ZodEncodeError, cr: ()=>globalConfig, + tm: ()=>NEVER, xI: ()=>$constructor }); var _util_js__rspack_import_0 = __webpack_require__("./node_modules/zod/v4/core/util.js"); var _a; - const NEVER = null && Object.freeze({ + const NEVER = Object.freeze({ status: "aborted" }); const _zodDesc = { @@ -23565,8 +23585,10 @@ var __webpack_modules__ = { var node_child_process__rspack_import_5 = __webpack_require__("node:child_process"); var _package_json__rspack_import_6 = __webpack_require__("./package.json"); var _codex_contract_js__rspack_import_7 = __webpack_require__("./src/core/codex/contract.js"); - var _desktop_shim_js__rspack_import_8 = __webpack_require__("./src/core/desktop-shim.js"); - var _user_machine_guidance_js__rspack_import_9 = __webpack_require__("./src/core/user-machine-guidance.js"); + var _codex_remote_control_js__rspack_import_8 = __webpack_require__("./src/core/codex/remote-control.js"); + var _codex_thread_id_js__rspack_import_11 = __webpack_require__("./src/core/codex/thread-id.js"); + var _desktop_shim_js__rspack_import_9 = __webpack_require__("./src/core/desktop-shim.js"); + var _user_machine_guidance_js__rspack_import_10 = __webpack_require__("./src/core/user-machine-guidance.js"); const PINNED_CODEX_VERSION = "0.154.0"; const UPSTREAM_DESKTOP_ISSUES = [ "https://github.com/openai/codex/issues/41014", @@ -23603,11 +23625,11 @@ var __webpack_modules__ = { function boxUnreachableMessage(path) { return [ "No Codex app-server control socket at " + path + ".", - _user_machine_guidance_js__rspack_import_9.M + _user_machine_guidance_js__rspack_import_10.M ].join("\n"); } function unreachableMessage(path, desktopAttached = "unknown", env = process.env) { - if ((0, _user_machine_guidance_js__rspack_import_9.R)({ + if ((0, _user_machine_guidance_js__rspack_import_10.R)({ path, env, home: env.HOME || (0, node_os__rspack_import_3.homedir)() @@ -24334,7 +24356,7 @@ var __webpack_modules__ = { let desktopShimConfigured = Boolean(shim && shim.installed && shim.wrapperPointsAtShim); if (shim === undefined) { try { - const live = (0, _desktop_shim_js__rspack_import_8.em)({ + const live = (0, _desktop_shim_js__rspack_import_9.em)({ env }); desktopShimConfigured = Boolean(live.installed && live.wrapperPointsAtShim); @@ -24443,33 +24465,52 @@ var __webpack_modules__ = { } const { client } = await openSession(env); try { - const params = { + const baseParams = { limit, - useStateDbOnly: true, modelProviders, ...cursor !== undefined ? { cursor } : {} }; let out; + let usedStateDbOnly = true; try { - out = await client.request("thread/list", params); + out = await client.request("thread/list", { + ...baseParams, + useStateDbOnly: true + }); } catch (err) { throw transportError(err); } if (!isObject(out) || !Array.isArray(out.data)) throw new CodexProtocolError("thread/list", "missing `data` array"); + if (out.data.length === 0 && cursor === undefined && (out.nextCursor == null || out.nextCursor === "")) { + try { + out = await client.request("thread/list", { + ...baseParams, + useStateDbOnly: false + }); + usedStateDbOnly = false; + } catch (err) { + throw transportError(err); + } + if (!isObject(out) || !Array.isArray(out.data)) throw new CodexProtocolError("thread/list", "missing `data` array"); + } if (out.nextCursor != null && typeof out.nextCursor !== "string") throw new CodexProtocolError("thread/list", "`nextCursor` is not a string"); const threads = out.data.map(summarizeThread); return { threads, nextCursor: out.nextCursor ?? null, - limit + limit, + useStateDbOnly: usedStateDbOnly }; } finally{ client.close(); } } - function explainSendError(err, threadId) { + function explainSendError(err, threadId, env = process.env) { + if (err instanceof _codex_remote_control_js__rspack_import_8.Rg) return err; + const mapped = (0, _codex_remote_control_js__rspack_import_8.R3)(err, threadId, env); + if (mapped instanceof _codex_remote_control_js__rspack_import_8.Rg) return mapped; if (!(err instanceof CodexRpcError)) return err; const msg = String(err.rpc && err.rpc.message || ""); if (/no rollout found|thread not found/i.test(msg)) { @@ -24544,12 +24585,19 @@ var __webpack_modules__ = { function assertThreadAllowed(threadId, env = process.env) { const raw = env.GROK_BOT_CODEX_THREADS; if (raw == null || raw.trim() === "") return; - const allowed = raw.split(",").map((s)=>s.trim()).filter(Boolean); - if (!allowed.includes(threadId)) { - throw new CodexSendError("Codex thread " + threadId + " is not in GROK_BOT_CODEX_THREADS; the operator allows only: " + allowed.join(", "), { + const bare = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); + const allowed = raw.split(",").map((s)=>{ + try { + return (0, _codex_thread_id_js__rspack_import_11.SX)(s.trim()); + } catch { + return s.trim(); + } + }).filter(Boolean); + if (!allowed.includes(bare)) { + throw new CodexSendError("Codex thread " + bare + " is not in GROK_BOT_CODEX_THREADS; the operator allows only: " + allowed.join(", "), { delivery: "rejected", reason: "route-not-allowed", - threadId + threadId: bare }); } } @@ -24619,6 +24667,7 @@ var __webpack_modules__ = { } async function listCodexQueue(threadId, { env = process.env, limit = 50, cursor } = {}) { requireExperimental(env, "gbot codex queue"); + threadId = normalizeCodexThreadId(threadId); const { client } = await openSession(env, { experimental: true }); @@ -24649,6 +24698,58 @@ var __webpack_modules__ = { client.close(); } } + async function readCodexThread(threadId, { limit = 100, env = process.env } = {}) { + if (!Number.isInteger(limit) || limit < 1 || limit > 2000) { + throw new RangeError("limit must be an integer 1-2000"); + } + const bare = normalizeCodexThreadId(threadId); + const { client } = await openSession(env); + try { + let meta; + try { + meta = await client.request("thread/read", { + threadId: bare + }); + } catch (err) { + const mapped = explainSendError(err, bare, env); + if (mapped instanceof RemoteThreadNotLoadedError) throw mapped; + throw transportError(err); + } + const turns = []; + let cursor; + for(let page = 0; page < 40 && turns.length < limit; page++){ + let out; + try { + out = await client.request("thread/turns/list", { + threadId: bare, + limit: Math.min(100, limit - turns.length), + itemsView: "full", + ...cursor !== undefined ? { + cursor + } : {} + }); + } catch (err) { + const mapped = explainSendError(err, bare, env); + if (mapped instanceof RemoteThreadNotLoadedError) throw mapped; + throw transportError(err); + } + if (!isObject(out) || !Array.isArray(out.data)) { + throw new CodexProtocolError("thread/turns/list", "missing `data` array"); + } + for (const row of out.data)turns.push(row); + if (out.nextCursor == null || typeof out.nextCursor !== "string") break; + cursor = out.nextCursor; + } + return { + threadId: bare, + thread: isObject(meta) && isObject(meta.thread) ? meta.thread : null, + turns: turns.slice(0, limit), + nextCursor: cursor ?? null + }; + } finally{ + client.close(); + } + } async function sendToCodexThread(threadId, text, { env = process.env, envelope = buildEnvelope({ env }), whenBusy = "reject", session, expectedTurnId, expectedCwd, signal } = {}) { @@ -24680,7 +24781,7 @@ var __webpack_modules__ = { ] : [] ].includes(whenBusy)) throw new RangeError("--when-busy must be reject, queue, or persistent steer"); if (whenBusy === "steer" && (typeof expectedTurnId !== "string" || !ID_PATTERN.test(expectedTurnId))) throw new RangeError("steer requires expectedTurnId"); - if (typeof threadId !== "string" || !ID_PATTERN.test(threadId)) throw new RangeError("Invalid threadId"); + threadId = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > WS_MAX_MESSAGE_BYTES) throw new RangeError("Message must contain text within 4 MiB"); if (!envelope || typeof envelope.messageId !== "string" || !ID_PATTERN.test(envelope.messageId)) throw new RangeError("Invalid envelope messageId"); const validated = buildEnvelope({ @@ -24721,8 +24822,10 @@ var __webpack_modules__ = { }); } catch (err) { assertNotCancelled(); - if (err instanceof CodexSendError) throw err; - throw new CodexSendError(explainSendError(err, threadId).message, { + if (err instanceof CodexSendError || err instanceof _codex_remote_control_js__rspack_import_8.Rg) throw err; + const explained = explainSendError(err, threadId, env); + if (explained instanceof _codex_remote_control_js__rspack_import_8.Rg) throw explained; + throw new CodexSendError(explained.message, { delivery: err instanceof CodexRpcError ? "rejected" : err && err.delivery || "unknown", reason: err instanceof CodexRpcError ? /no rollout found|thread not found/i.test(String(err.rpc && err.rpc.message)) ? "unknown-thread" : /active writer/i.test(String(err.rpc && err.rpc.message)) ? "external-owner" : "rejected" : "transport", threadId, @@ -24950,7 +25053,11 @@ var __webpack_modules__ = { "messageId", "correlationId", "refused", - "hop" + "hop", + "hostId", + "hostName", + "hint", + "code" ]){ if (error[key] !== undefined) out[key] = error[key]; } @@ -24986,9 +25093,12 @@ var __webpack_modules__ = { var _contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); var node_fs__rspack_import_1 = __webpack_require__("node:fs"); var _codex_bridge_js__rspack_import_2 = __webpack_require__("./src/core/codex-bridge.js"); + var _remote_control_js__rspack_import_3 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_id_js__rspack_import_4 = __webpack_require__("./src/core/codex/thread-id.js"); const ID = /^[A-Za-z0-9_.:-]{1,128}$/; const BUDGET = 4 * 1024 * 1024; function conversationId(value, name = 'threadId') { + if (name === 'threadId') return (0, _thread_id_js__rspack_import_4.SX)(value); if (typeof value !== 'string' || !ID.test(value)) throw new RangeError(`${name} must be 1-128 identifier characters`); return value; } @@ -25113,7 +25223,8 @@ var __webpack_modules__ = { if (expected !== undefined && (typeof cwd !== 'string' || (0, node_fs__rspack_import_1.realpathSync)(cwd) !== expected)) throw new Error('Codex thread cwd does not match expectedCwd'); } catch (error) { await close(); - throw error; + if (error instanceof _remote_control_js__rspack_import_3.Rg) throw error; + throw (0, _remote_control_js__rspack_import_3.R3)(error, threadId, env); } async function wait({ turnId, messageId, afterMessageId, timeoutMs = 120000, signal: waitSignal, maxOutputBytes = 1048576 }) { conversationId(turnId, 'turnId'); @@ -25419,6 +25530,263 @@ var __webpack_modules__ = { j: ()=>openCodexConversation }); }, + "./src/core/codex/remote-control.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var node_os__rspack_import_1 = __webpack_require__("node:os"); + var node_path__rspack_import_2 = __webpack_require__("node:path"); + var _thread_id_js__rspack_import_3 = __webpack_require__("./src/core/codex/thread-id.js"); + const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; + class RemoteThreadNotLoadedError1 extends Error { + constructor(threadId, hostId = null, hostName = null){ + const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; + const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); + this.name = 'RemoteThreadNotLoadedError'; + this.code = 'REMOTE_THREAD_NOT_LOADED'; + this.delivery = 'rejected'; + this.reason = 'remote-thread-not-loaded'; + this.threadId = threadId; + this.hostId = hostId; + this.hostName = hostName; + this.hint = hint; + } + } + function codexGlobalStatePath(env = process.env) { + const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); + return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); + } + function loadCodexGlobalState(env = process.env) { + let raw; + try { + raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); + } catch { + return null; + } + try { + const data = JSON.parse(raw); + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + return data; + } catch { + return null; + } + } + function findRemoteThreadHost(threadId, env = process.env) { + let bare; + try { + bare = (0, _thread_id_js__rspack_import_3.SX)(threadId); + } catch { + bare = typeof threadId === 'string' && threadId.startsWith("local:") ? threadId.slice("local:".length) : threadId; + } + if (!bare) return null; + const data = loadCodexGlobalState(env); + if (!data) return null; + const hostNames = collectHostNames(data); + for (const [key, value] of Object.entries(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match?.[1]) continue; + const hostId = match[1]; + const hostName = hostNames.get(hostId) ?? extractHostName(value) ?? null; + for (const entry of extractThreadEntries(value)){ + const id = threadIdFromEntry(entry); + if (!id) continue; + const entryBare = id.startsWith("local:") ? id.slice("local:".length) : id; + if (entryBare === bare) return { + hostId, + hostName + }; + } + } + return null; + } + function mapRemoteThreadError(error, threadId, env = process.env) { + const message = errorMessage(error); + if (!/thread not loaded|not loaded|no rollout found|thread not found|invalid thread id/i.test(message)) { + return error instanceof Error ? error : new Error(message || String(error)); + } + const remote = findRemoteThreadHost(threadId, env); + if (remote) { + return new RemoteThreadNotLoadedError1(threadId, remote.hostId, remote.hostName); + } + if (/thread not loaded|not loaded/i.test(message)) { + return new RemoteThreadNotLoadedError1(threadId, null, null); + } + return error instanceof Error ? error : new Error(message || String(error)); + } + function collectHostNames(data) { + const names = new Map(); + for (const [key, value] of Object.entries(data)){ + if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; + if (!value || typeof value !== 'object') continue; + if (Array.isArray(value)) { + for (const entry of value){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + continue; + } + for (const [hostId, entry] of Object.entries(value)){ + const fromEntry = hostNameFromEntry(entry); + if (fromEntry) { + names.set(fromEntry.hostId, fromEntry.hostName); + continue; + } + const label = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (label) names.set(hostId, label); + } + } + return names; + } + function hostNameFromEntry(entry) { + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + const hostId = stringField(entry, [ + 'hostId', + 'id', + 'host_id', + 'uuid' + ]); + const hostName = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (!hostId || !hostName) return null; + return { + hostId, + hostName + }; + } + function extractHostName(value) { + if (!value || typeof value !== 'object' || Array.isArray(value)) return null; + return stringField(value, [ + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName' + ]); + } + function extractThreadEntries(value) { + if (Array.isArray(value)) return value; + if (!value || typeof value !== 'object') return []; + const record = value; + for (const key of [ + 'threads', + 'summaries', + 'items', + 'data', + 'conversations' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + const entries = []; + for (const [key, entry] of Object.entries(record)){ + if ([ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName', + 'hostId', + 'version' + ].includes(key)) continue; + if (typeof entry === 'string') continue; + if (entry && typeof entry === 'object' && !Array.isArray(entry)) { + const id = stringField(entry, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]); + entries.push(id ? entry : { + ...entry, + id: key + }); + } + } + return entries; + } + function threadIdFromEntry(entry) { + if (typeof entry === 'string' && entry) return entry; + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + return stringField(entry, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]); + } + function stringField(row, keys) { + if (!row || typeof row !== 'object' || Array.isArray(row)) return null; + for (const key of keys){ + const value = row[key]; + if (typeof value === 'string' && value.trim()) return value.trim(); + } + return null; + } + function errorMessage(error) { + if (!error) return ''; + if (typeof error === 'string') return error; + if (error instanceof Error) return error.message; + if (typeof error === 'object' && error && 'message' in error) return String(error.message); + if (typeof error === 'object' && error && 'rpc' in error) { + const rpc = error.rpc; + if (rpc && typeof rpc.message === 'string') return rpc.message; + } + return String(error); + } + __webpack_require__.d(__webpack_exports__, { + R3: ()=>mapRemoteThreadError, + Rg: ()=>RemoteThreadNotLoadedError1 + }); + }, + "./src/core/codex/thread-id.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { + const LOCAL_THREAD_ID_PREFIX = 'local:'; + const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; + const ID_PATTERN = /^[A-Za-z0-9_.:-]{1,128}$/; + function isTemporaryDesktopThreadId(threadId) { + return typeof threadId === 'string' && threadId.startsWith(TEMP_THREAD_ID_PREFIX); + } + function normalizeCodexThreadId1(threadId) { + if (typeof threadId !== 'string' || !threadId) { + throw new RangeError('Invalid threadId'); + } + if (isTemporaryDesktopThreadId(threadId)) { + throw new RangeError('Temporary Desktop thread id ' + JSON.stringify(threadId) + ' has no app-server mapping; wait for the real conversation id'); + } + const bare = threadId.startsWith(LOCAL_THREAD_ID_PREFIX) ? threadId.slice(LOCAL_THREAD_ID_PREFIX.length) : threadId; + if (!bare || !ID_PATTERN.test(bare)) { + throw new RangeError('Invalid threadId'); + } + return bare; + } + function hasLocalThreadPrefix(threadId) { + return typeof threadId === 'string' && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) && !isTemporaryDesktopThreadId(threadId); + } + __webpack_require__.d(__webpack_exports__, { + SX: ()=>normalizeCodexThreadId1, + vr: ()=>isTemporaryDesktopThreadId + }, { + hA: TEMP_THREAD_ID_PREFIX + }); + }, "./src/core/desktop-shim.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { var node_child_process__rspack_import_0 = __webpack_require__("node:child_process"); var node_fs__rspack_import_1 = __webpack_require__("node:fs"); @@ -27838,10 +28206,11 @@ const routes = Object.freeze({ "additionalProperties": false, "properties": { "cursor": { + "description": "Opaque nextCursor from a previous page.", "type": "string" }, "limit": { - "description": "Maximum threads in this page: 1-200.", + "description": "Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.", "type": "number" } }, diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index da9edbe..561d9f1 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -7887,6 +7887,7 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); class NotImplementedError extends Error { code = 'NOT_IMPLEMENTED'; delivery = 'rejected'; @@ -7914,29 +7915,15 @@ var __webpack_modules__ = { this.name = 'CdpUnreachableError'; } } - class RemoteThreadNotLoadedError extends Error { - code = 'REMOTE_THREAD_NOT_LOADED'; - delivery = 'rejected'; - reason = 'remote-thread-not-loaded'; - threadId; - hostId; - hostName; - hint; + class RemoteThreadNotLoadedError1 extends _codex_remote_control_js__rspack_import_0.Rg { constructor(threadId, hostId = null, hostName = null){ - const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; - const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; - const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; - super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); + super(threadId, hostId, hostName); this.name = 'RemoteThreadNotLoadedError'; - this.threadId = threadId; - this.hostId = hostId; - this.hostName = hostName; - this.hint = hint; } } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, - Rg: ()=>RemoteThreadNotLoadedError, + Rg: ()=>RemoteThreadNotLoadedError1, c$: ()=>CdpHostRejectedError, sO: ()=>CdpUnreachableError }); @@ -8049,6 +8036,22 @@ var __webpack_modules__ = { ...host } ])); + for (const thread of remotes){ + const existing = byId.get(thread.hostId); + if (existing) { + byId.set(thread.hostId, { + ...existing, + hostName: existing.hostName ?? thread.hostName + }); + } else { + byId.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName, + location: 'remote', + threadCount: 0 + }); + } + } let hostsSource = 'remote-thread-summaries-v3+local'; try { const discoverEnvs = this.#fallbacks.discoverRemoteEnvironments ?? _app_server_fallback_js__rspack_import_1.OP; @@ -9186,19 +9189,21 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/thread-ids.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_thread_id_js__rspack_import_1 = __webpack_require__("./src/core/codex/thread-id.js"); var _cdp_dom_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); - const LOCAL_THREAD_ID_PREFIX = 'local:'; + const LOCAL_THREAD_ID_PREFIX = "local:"; + const TEMP_THREAD_ID_PREFIX = null && CDP_TEMP_PREFIX; const HISTORY_CONTENT_TURN_PREFIX = 'history-content:turn:'; function isTemporaryDesktopThreadId(threadId) { - return threadId.startsWith(_cdp_dom_js__rspack_import_0.hA); + return (0, _codex_thread_id_js__rspack_import_1.vr)(threadId) || threadId.startsWith(_codex_thread_id_js__rspack_import_1.hA); } function toAppServerThreadId(threadId) { if (!threadId || isTemporaryDesktopThreadId(threadId)) return null; - if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) { - const bare = threadId.slice(LOCAL_THREAD_ID_PREFIX.length); - return bare || null; + try { + return (0, _codex_thread_id_js__rspack_import_1.SX)(threadId); + } catch { + return null; } - return threadId; } function requireAppServerThreadId(threadId) { const bare = toAppServerThreadId(threadId); @@ -9283,10 +9288,23 @@ var __webpack_modules__ = { }, "./src/core/codex/routes.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var zod__rspack_import_3 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); + var zod__rspack_import_5 = __webpack_require__("./node_modules/zod/v4/core/core.js"); var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); var _contract_js__rspack_import_1 = __webpack_require__("./src/core/codex/contract.js"); var _conversation_js__rspack_import_2 = __webpack_require__("./src/core/codex/conversation.js"); - const id = zod__rspack_import_3.YjP().regex(/^[A-Za-z0-9_.:-]{1,128}$/); + var _thread_id_js__rspack_import_4 = __webpack_require__("./src/core/codex/thread-id.js"); + const bareId = zod__rspack_import_3.YjP().regex(/^[A-Za-z0-9_.:-]{1,128}$/); + const id = zod__rspack_import_3.YjP().min(1).max(160).transform((value, ctx)=>{ + try { + return (0, _thread_id_js__rspack_import_4.SX)(value); + } catch (error) { + ctx.addIssue({ + code: 'custom', + message: error instanceof Error ? error.message : 'Invalid threadId' + }); + return zod__rspack_import_5.tm; + } + }).pipe(bareId); const observationFields = { expectedCwd: zod__rspack_import_3.YjP().min(1).optional(), threadId: id, @@ -10370,10 +10388,11 @@ var __webpack_modules__ = { properties: { "limit": { "type": "number", - "description": "Maximum threads in this page: 1-200." + "description": "Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page." }, "cursor": { - "type": "string" + "type": "string", + "description": "Opaque nextCursor from a previous page." } }, required: [] @@ -59690,10 +59709,11 @@ var __webpack_modules__ = { "additionalProperties": false, "properties": { "cursor": { + "description": "Opaque nextCursor from a previous page.", "type": "string" }, "limit": { - "description": "Maximum threads in this page: 1-200.", + "description": "Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.", "type": "number" } }, @@ -60605,8 +60625,10 @@ var __webpack_modules__ = { var node_child_process__rspack_import_5 = __webpack_require__("node:child_process"); var _package_json__rspack_import_6 = __webpack_require__("./package.json"); var _codex_contract_js__rspack_import_7 = __webpack_require__("./src/core/codex/contract.js"); - var _desktop_shim_js__rspack_import_8 = __webpack_require__("./src/core/desktop-shim.js"); - var _user_machine_guidance_js__rspack_import_9 = __webpack_require__("./src/core/user-machine-guidance.js"); + var _codex_remote_control_js__rspack_import_8 = __webpack_require__("./src/core/codex/remote-control.js"); + var _codex_thread_id_js__rspack_import_11 = __webpack_require__("./src/core/codex/thread-id.js"); + var _desktop_shim_js__rspack_import_9 = __webpack_require__("./src/core/desktop-shim.js"); + var _user_machine_guidance_js__rspack_import_10 = __webpack_require__("./src/core/user-machine-guidance.js"); const PINNED_CODEX_VERSION = "0.154.0"; const UPSTREAM_DESKTOP_ISSUES = [ "https://github.com/openai/codex/issues/41014", @@ -60643,11 +60665,11 @@ var __webpack_modules__ = { function boxUnreachableMessage(path) { return [ "No Codex app-server control socket at " + path + ".", - _user_machine_guidance_js__rspack_import_9.M + _user_machine_guidance_js__rspack_import_10.M ].join("\n"); } function unreachableMessage(path, desktopAttached = "unknown", env = process.env) { - if ((0, _user_machine_guidance_js__rspack_import_9.R)({ + if ((0, _user_machine_guidance_js__rspack_import_10.R)({ path, env, home: env.HOME || (0, node_os__rspack_import_3.homedir)() @@ -61374,7 +61396,7 @@ var __webpack_modules__ = { let desktopShimConfigured = Boolean(shim && shim.installed && shim.wrapperPointsAtShim); if (shim === undefined) { try { - const live = (0, _desktop_shim_js__rspack_import_8.em)({ + const live = (0, _desktop_shim_js__rspack_import_9.em)({ env }); desktopShimConfigured = Boolean(live.installed && live.wrapperPointsAtShim); @@ -61483,33 +61505,52 @@ var __webpack_modules__ = { } const { client } = await openSession(env); try { - const params = { + const baseParams = { limit, - useStateDbOnly: true, modelProviders, ...cursor !== undefined ? { cursor } : {} }; let out; + let usedStateDbOnly = true; try { - out = await client.request("thread/list", params); + out = await client.request("thread/list", { + ...baseParams, + useStateDbOnly: true + }); } catch (err) { throw transportError(err); } if (!isObject(out) || !Array.isArray(out.data)) throw new CodexProtocolError("thread/list", "missing `data` array"); + if (out.data.length === 0 && cursor === undefined && (out.nextCursor == null || out.nextCursor === "")) { + try { + out = await client.request("thread/list", { + ...baseParams, + useStateDbOnly: false + }); + usedStateDbOnly = false; + } catch (err) { + throw transportError(err); + } + if (!isObject(out) || !Array.isArray(out.data)) throw new CodexProtocolError("thread/list", "missing `data` array"); + } if (out.nextCursor != null && typeof out.nextCursor !== "string") throw new CodexProtocolError("thread/list", "`nextCursor` is not a string"); const threads = out.data.map(summarizeThread); return { threads, nextCursor: out.nextCursor ?? null, - limit + limit, + useStateDbOnly: usedStateDbOnly }; } finally{ client.close(); } } - function explainSendError(err, threadId) { + function explainSendError(err, threadId, env = process.env) { + if (err instanceof _codex_remote_control_js__rspack_import_8.Rg) return err; + const mapped = (0, _codex_remote_control_js__rspack_import_8.R3)(err, threadId, env); + if (mapped instanceof _codex_remote_control_js__rspack_import_8.Rg) return mapped; if (!(err instanceof CodexRpcError)) return err; const msg = String(err.rpc && err.rpc.message || ""); if (/no rollout found|thread not found/i.test(msg)) { @@ -61584,12 +61625,19 @@ var __webpack_modules__ = { function assertThreadAllowed(threadId, env = process.env) { const raw = env.GROK_BOT_CODEX_THREADS; if (raw == null || raw.trim() === "") return; - const allowed = raw.split(",").map((s)=>s.trim()).filter(Boolean); - if (!allowed.includes(threadId)) { - throw new CodexSendError("Codex thread " + threadId + " is not in GROK_BOT_CODEX_THREADS; the operator allows only: " + allowed.join(", "), { + const bare = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); + const allowed = raw.split(",").map((s)=>{ + try { + return (0, _codex_thread_id_js__rspack_import_11.SX)(s.trim()); + } catch { + return s.trim(); + } + }).filter(Boolean); + if (!allowed.includes(bare)) { + throw new CodexSendError("Codex thread " + bare + " is not in GROK_BOT_CODEX_THREADS; the operator allows only: " + allowed.join(", "), { delivery: "rejected", reason: "route-not-allowed", - threadId + threadId: bare }); } } @@ -61659,6 +61707,7 @@ var __webpack_modules__ = { } async function listCodexQueue(threadId, { env = process.env, limit = 50, cursor } = {}) { requireExperimental(env, "gbot codex queue"); + threadId = normalizeCodexThreadId(threadId); const { client } = await openSession(env, { experimental: true }); @@ -61689,6 +61738,58 @@ var __webpack_modules__ = { client.close(); } } + async function readCodexThread(threadId, { limit = 100, env = process.env } = {}) { + if (!Number.isInteger(limit) || limit < 1 || limit > 2000) { + throw new RangeError("limit must be an integer 1-2000"); + } + const bare = normalizeCodexThreadId(threadId); + const { client } = await openSession(env); + try { + let meta; + try { + meta = await client.request("thread/read", { + threadId: bare + }); + } catch (err) { + const mapped = explainSendError(err, bare, env); + if (mapped instanceof RemoteThreadNotLoadedError) throw mapped; + throw transportError(err); + } + const turns = []; + let cursor; + for(let page = 0; page < 40 && turns.length < limit; page++){ + let out; + try { + out = await client.request("thread/turns/list", { + threadId: bare, + limit: Math.min(100, limit - turns.length), + itemsView: "full", + ...cursor !== undefined ? { + cursor + } : {} + }); + } catch (err) { + const mapped = explainSendError(err, bare, env); + if (mapped instanceof RemoteThreadNotLoadedError) throw mapped; + throw transportError(err); + } + if (!isObject(out) || !Array.isArray(out.data)) { + throw new CodexProtocolError("thread/turns/list", "missing `data` array"); + } + for (const row of out.data)turns.push(row); + if (out.nextCursor == null || typeof out.nextCursor !== "string") break; + cursor = out.nextCursor; + } + return { + threadId: bare, + thread: isObject(meta) && isObject(meta.thread) ? meta.thread : null, + turns: turns.slice(0, limit), + nextCursor: cursor ?? null + }; + } finally{ + client.close(); + } + } async function sendToCodexThread(threadId, text, { env = process.env, envelope = buildEnvelope({ env }), whenBusy = "reject", session, expectedTurnId, expectedCwd, signal } = {}) { @@ -61720,7 +61821,7 @@ var __webpack_modules__ = { ] : [] ].includes(whenBusy)) throw new RangeError("--when-busy must be reject, queue, or persistent steer"); if (whenBusy === "steer" && (typeof expectedTurnId !== "string" || !ID_PATTERN.test(expectedTurnId))) throw new RangeError("steer requires expectedTurnId"); - if (typeof threadId !== "string" || !ID_PATTERN.test(threadId)) throw new RangeError("Invalid threadId"); + threadId = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > WS_MAX_MESSAGE_BYTES) throw new RangeError("Message must contain text within 4 MiB"); if (!envelope || typeof envelope.messageId !== "string" || !ID_PATTERN.test(envelope.messageId)) throw new RangeError("Invalid envelope messageId"); const validated = buildEnvelope({ @@ -61761,8 +61862,10 @@ var __webpack_modules__ = { }); } catch (err) { assertNotCancelled(); - if (err instanceof CodexSendError) throw err; - throw new CodexSendError(explainSendError(err, threadId).message, { + if (err instanceof CodexSendError || err instanceof _codex_remote_control_js__rspack_import_8.Rg) throw err; + const explained = explainSendError(err, threadId, env); + if (explained instanceof _codex_remote_control_js__rspack_import_8.Rg) throw explained; + throw new CodexSendError(explained.message, { delivery: err instanceof CodexRpcError ? "rejected" : err && err.delivery || "unknown", reason: err instanceof CodexRpcError ? /no rollout found|thread not found/i.test(String(err.rpc && err.rpc.message)) ? "unknown-thread" : /active writer/i.test(String(err.rpc && err.rpc.message)) ? "external-owner" : "rejected" : "transport", threadId, @@ -61990,7 +62093,11 @@ var __webpack_modules__ = { "messageId", "correlationId", "refused", - "hop" + "hop", + "hostId", + "hostName", + "hint", + "code" ]){ if (error[key] !== undefined) out[key] = error[key]; } @@ -62026,9 +62133,12 @@ var __webpack_modules__ = { var _contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); var node_fs__rspack_import_1 = __webpack_require__("node:fs"); var _codex_bridge_js__rspack_import_2 = __webpack_require__("./src/core/codex-bridge.js"); + var _remote_control_js__rspack_import_3 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_id_js__rspack_import_4 = __webpack_require__("./src/core/codex/thread-id.js"); const ID = /^[A-Za-z0-9_.:-]{1,128}$/; const BUDGET = 4 * 1024 * 1024; function conversationId(value, name = 'threadId') { + if (name === 'threadId') return (0, _thread_id_js__rspack_import_4.SX)(value); if (typeof value !== 'string' || !ID.test(value)) throw new RangeError(`${name} must be 1-128 identifier characters`); return value; } @@ -62153,7 +62263,8 @@ var __webpack_modules__ = { if (expected !== undefined && (typeof cwd !== 'string' || (0, node_fs__rspack_import_1.realpathSync)(cwd) !== expected)) throw new Error('Codex thread cwd does not match expectedCwd'); } catch (error) { await close(); - throw error; + if (error instanceof _remote_control_js__rspack_import_3.Rg) throw error; + throw (0, _remote_control_js__rspack_import_3.R3)(error, threadId, env); } async function wait({ turnId, messageId, afterMessageId, timeoutMs = 120000, signal: waitSignal, maxOutputBytes = 1048576 }) { conversationId(turnId, 'turnId'); @@ -62459,6 +62570,263 @@ var __webpack_modules__ = { j: ()=>openCodexConversation }); }, + "./src/core/codex/remote-control.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var node_os__rspack_import_1 = __webpack_require__("node:os"); + var node_path__rspack_import_2 = __webpack_require__("node:path"); + var _thread_id_js__rspack_import_3 = __webpack_require__("./src/core/codex/thread-id.js"); + const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; + class RemoteThreadNotLoadedError1 extends Error { + constructor(threadId, hostId = null, hostName = null){ + const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; + const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); + this.name = 'RemoteThreadNotLoadedError'; + this.code = 'REMOTE_THREAD_NOT_LOADED'; + this.delivery = 'rejected'; + this.reason = 'remote-thread-not-loaded'; + this.threadId = threadId; + this.hostId = hostId; + this.hostName = hostName; + this.hint = hint; + } + } + function codexGlobalStatePath(env = process.env) { + const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); + return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); + } + function loadCodexGlobalState(env = process.env) { + let raw; + try { + raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); + } catch { + return null; + } + try { + const data = JSON.parse(raw); + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + return data; + } catch { + return null; + } + } + function findRemoteThreadHost(threadId, env = process.env) { + let bare; + try { + bare = (0, _thread_id_js__rspack_import_3.SX)(threadId); + } catch { + bare = typeof threadId === 'string' && threadId.startsWith("local:") ? threadId.slice("local:".length) : threadId; + } + if (!bare) return null; + const data = loadCodexGlobalState(env); + if (!data) return null; + const hostNames = collectHostNames(data); + for (const [key, value] of Object.entries(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match?.[1]) continue; + const hostId = match[1]; + const hostName = hostNames.get(hostId) ?? extractHostName(value) ?? null; + for (const entry of extractThreadEntries(value)){ + const id = threadIdFromEntry(entry); + if (!id) continue; + const entryBare = id.startsWith("local:") ? id.slice("local:".length) : id; + if (entryBare === bare) return { + hostId, + hostName + }; + } + } + return null; + } + function mapRemoteThreadError(error, threadId, env = process.env) { + const message = errorMessage(error); + if (!/thread not loaded|not loaded|no rollout found|thread not found|invalid thread id/i.test(message)) { + return error instanceof Error ? error : new Error(message || String(error)); + } + const remote = findRemoteThreadHost(threadId, env); + if (remote) { + return new RemoteThreadNotLoadedError1(threadId, remote.hostId, remote.hostName); + } + if (/thread not loaded|not loaded/i.test(message)) { + return new RemoteThreadNotLoadedError1(threadId, null, null); + } + return error instanceof Error ? error : new Error(message || String(error)); + } + function collectHostNames(data) { + const names = new Map(); + for (const [key, value] of Object.entries(data)){ + if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; + if (!value || typeof value !== 'object') continue; + if (Array.isArray(value)) { + for (const entry of value){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + continue; + } + for (const [hostId, entry] of Object.entries(value)){ + const fromEntry = hostNameFromEntry(entry); + if (fromEntry) { + names.set(fromEntry.hostId, fromEntry.hostName); + continue; + } + const label = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (label) names.set(hostId, label); + } + } + return names; + } + function hostNameFromEntry(entry) { + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + const hostId = stringField(entry, [ + 'hostId', + 'id', + 'host_id', + 'uuid' + ]); + const hostName = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (!hostId || !hostName) return null; + return { + hostId, + hostName + }; + } + function extractHostName(value) { + if (!value || typeof value !== 'object' || Array.isArray(value)) return null; + return stringField(value, [ + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName' + ]); + } + function extractThreadEntries(value) { + if (Array.isArray(value)) return value; + if (!value || typeof value !== 'object') return []; + const record = value; + for (const key of [ + 'threads', + 'summaries', + 'items', + 'data', + 'conversations' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + const entries = []; + for (const [key, entry] of Object.entries(record)){ + if ([ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName', + 'hostId', + 'version' + ].includes(key)) continue; + if (typeof entry === 'string') continue; + if (entry && typeof entry === 'object' && !Array.isArray(entry)) { + const id = stringField(entry, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]); + entries.push(id ? entry : { + ...entry, + id: key + }); + } + } + return entries; + } + function threadIdFromEntry(entry) { + if (typeof entry === 'string' && entry) return entry; + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + return stringField(entry, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]); + } + function stringField(row, keys) { + if (!row || typeof row !== 'object' || Array.isArray(row)) return null; + for (const key of keys){ + const value = row[key]; + if (typeof value === 'string' && value.trim()) return value.trim(); + } + return null; + } + function errorMessage(error) { + if (!error) return ''; + if (typeof error === 'string') return error; + if (error instanceof Error) return error.message; + if (typeof error === 'object' && error && 'message' in error) return String(error.message); + if (typeof error === 'object' && error && 'rpc' in error) { + const rpc = error.rpc; + if (rpc && typeof rpc.message === 'string') return rpc.message; + } + return String(error); + } + __webpack_require__.d(__webpack_exports__, { + R3: ()=>mapRemoteThreadError, + Rg: ()=>RemoteThreadNotLoadedError1 + }); + }, + "./src/core/codex/thread-id.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { + const LOCAL_THREAD_ID_PREFIX = 'local:'; + const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; + const ID_PATTERN = /^[A-Za-z0-9_.:-]{1,128}$/; + function isTemporaryDesktopThreadId(threadId) { + return typeof threadId === 'string' && threadId.startsWith(TEMP_THREAD_ID_PREFIX); + } + function normalizeCodexThreadId1(threadId) { + if (typeof threadId !== 'string' || !threadId) { + throw new RangeError('Invalid threadId'); + } + if (isTemporaryDesktopThreadId(threadId)) { + throw new RangeError('Temporary Desktop thread id ' + JSON.stringify(threadId) + ' has no app-server mapping; wait for the real conversation id'); + } + const bare = threadId.startsWith(LOCAL_THREAD_ID_PREFIX) ? threadId.slice(LOCAL_THREAD_ID_PREFIX.length) : threadId; + if (!bare || !ID_PATTERN.test(bare)) { + throw new RangeError('Invalid threadId'); + } + return bare; + } + function hasLocalThreadPrefix(threadId) { + return typeof threadId === 'string' && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) && !isTemporaryDesktopThreadId(threadId); + } + __webpack_require__.d(__webpack_exports__, { + SX: ()=>normalizeCodexThreadId1, + vr: ()=>isTemporaryDesktopThreadId + }, { + hA: TEMP_THREAD_ID_PREFIX + }); + }, "./src/core/desktop-shim.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { var node_child_process__rspack_import_0 = __webpack_require__("node:child_process"); var node_fs__rspack_import_1 = __webpack_require__("node:fs"); diff --git a/artifact/scripts/gbot-relay.mjs b/artifact/scripts/gbot-relay.mjs index b4e0677..ffb4eef 100644 --- a/artifact/scripts/gbot-relay.mjs +++ b/artifact/scripts/gbot-relay.mjs @@ -22133,8 +22133,10 @@ var __webpack_modules__ = { var node_child_process__rspack_import_5 = __webpack_require__("node:child_process"); var _package_json__rspack_import_6 = __webpack_require__("./package.json"); var _codex_contract_js__rspack_import_7 = __webpack_require__("./src/core/codex/contract.js"); - var _desktop_shim_js__rspack_import_8 = __webpack_require__("./src/core/desktop-shim.js"); - var _user_machine_guidance_js__rspack_import_9 = __webpack_require__("./src/core/user-machine-guidance.js"); + var _codex_remote_control_js__rspack_import_8 = __webpack_require__("./src/core/codex/remote-control.js"); + var _codex_thread_id_js__rspack_import_11 = __webpack_require__("./src/core/codex/thread-id.js"); + var _desktop_shim_js__rspack_import_9 = __webpack_require__("./src/core/desktop-shim.js"); + var _user_machine_guidance_js__rspack_import_10 = __webpack_require__("./src/core/user-machine-guidance.js"); const PINNED_CODEX_VERSION = "0.154.0"; const UPSTREAM_DESKTOP_ISSUES = [ "https://github.com/openai/codex/issues/41014", @@ -22171,11 +22173,11 @@ var __webpack_modules__ = { function boxUnreachableMessage(path) { return [ "No Codex app-server control socket at " + path + ".", - _user_machine_guidance_js__rspack_import_9.M + _user_machine_guidance_js__rspack_import_10.M ].join("\n"); } function unreachableMessage(path, desktopAttached = "unknown", env = process.env) { - if ((0, _user_machine_guidance_js__rspack_import_9.R)({ + if ((0, _user_machine_guidance_js__rspack_import_10.R)({ path, env, home: env.HOME || (0, node_os__rspack_import_3.homedir)() @@ -23011,33 +23013,52 @@ var __webpack_modules__ = { } const { client } = await openSession(env); try { - const params = { + const baseParams = { limit, - useStateDbOnly: true, modelProviders, ...cursor !== undefined ? { cursor } : {} }; let out; + let usedStateDbOnly = true; try { - out = await client.request("thread/list", params); + out = await client.request("thread/list", { + ...baseParams, + useStateDbOnly: true + }); } catch (err) { throw transportError(err); } if (!isObject(out) || !Array.isArray(out.data)) throw new CodexProtocolError("thread/list", "missing `data` array"); + if (out.data.length === 0 && cursor === undefined && (out.nextCursor == null || out.nextCursor === "")) { + try { + out = await client.request("thread/list", { + ...baseParams, + useStateDbOnly: false + }); + usedStateDbOnly = false; + } catch (err) { + throw transportError(err); + } + if (!isObject(out) || !Array.isArray(out.data)) throw new CodexProtocolError("thread/list", "missing `data` array"); + } if (out.nextCursor != null && typeof out.nextCursor !== "string") throw new CodexProtocolError("thread/list", "`nextCursor` is not a string"); const threads = out.data.map(summarizeThread); return { threads, nextCursor: out.nextCursor ?? null, - limit + limit, + useStateDbOnly: usedStateDbOnly }; } finally{ client.close(); } } - function explainSendError(err, threadId) { + function explainSendError(err, threadId, env = process.env) { + if (err instanceof _codex_remote_control_js__rspack_import_8.Rg) return err; + const mapped = (0, _codex_remote_control_js__rspack_import_8.R3)(err, threadId, env); + if (mapped instanceof _codex_remote_control_js__rspack_import_8.Rg) return mapped; if (!(err instanceof CodexRpcError)) return err; const msg = String(err.rpc && err.rpc.message || ""); if (/no rollout found|thread not found/i.test(msg)) { @@ -23112,12 +23133,19 @@ var __webpack_modules__ = { function assertThreadAllowed(threadId, env = process.env) { const raw = env.GROK_BOT_CODEX_THREADS; if (raw == null || raw.trim() === "") return; - const allowed = raw.split(",").map((s)=>s.trim()).filter(Boolean); - if (!allowed.includes(threadId)) { - throw new CodexSendError("Codex thread " + threadId + " is not in GROK_BOT_CODEX_THREADS; the operator allows only: " + allowed.join(", "), { + const bare = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); + const allowed = raw.split(",").map((s)=>{ + try { + return (0, _codex_thread_id_js__rspack_import_11.SX)(s.trim()); + } catch { + return s.trim(); + } + }).filter(Boolean); + if (!allowed.includes(bare)) { + throw new CodexSendError("Codex thread " + bare + " is not in GROK_BOT_CODEX_THREADS; the operator allows only: " + allowed.join(", "), { delivery: "rejected", reason: "route-not-allowed", - threadId + threadId: bare }); } } @@ -23187,6 +23215,7 @@ var __webpack_modules__ = { } async function listCodexQueue(threadId, { env = process.env, limit = 50, cursor } = {}) { requireExperimental(env, "gbot codex queue"); + threadId = normalizeCodexThreadId(threadId); const { client } = await openSession(env, { experimental: true }); @@ -23217,6 +23246,58 @@ var __webpack_modules__ = { client.close(); } } + async function readCodexThread(threadId, { limit = 100, env = process.env } = {}) { + if (!Number.isInteger(limit) || limit < 1 || limit > 2000) { + throw new RangeError("limit must be an integer 1-2000"); + } + const bare = normalizeCodexThreadId(threadId); + const { client } = await openSession(env); + try { + let meta; + try { + meta = await client.request("thread/read", { + threadId: bare + }); + } catch (err) { + const mapped = explainSendError(err, bare, env); + if (mapped instanceof RemoteThreadNotLoadedError) throw mapped; + throw transportError(err); + } + const turns = []; + let cursor; + for(let page = 0; page < 40 && turns.length < limit; page++){ + let out; + try { + out = await client.request("thread/turns/list", { + threadId: bare, + limit: Math.min(100, limit - turns.length), + itemsView: "full", + ...cursor !== undefined ? { + cursor + } : {} + }); + } catch (err) { + const mapped = explainSendError(err, bare, env); + if (mapped instanceof RemoteThreadNotLoadedError) throw mapped; + throw transportError(err); + } + if (!isObject(out) || !Array.isArray(out.data)) { + throw new CodexProtocolError("thread/turns/list", "missing `data` array"); + } + for (const row of out.data)turns.push(row); + if (out.nextCursor == null || typeof out.nextCursor !== "string") break; + cursor = out.nextCursor; + } + return { + threadId: bare, + thread: isObject(meta) && isObject(meta.thread) ? meta.thread : null, + turns: turns.slice(0, limit), + nextCursor: cursor ?? null + }; + } finally{ + client.close(); + } + } async function sendToCodexThread(threadId, text, { env = process.env, envelope = buildEnvelope({ env }), whenBusy = "reject", session, expectedTurnId, expectedCwd, signal } = {}) { @@ -23248,7 +23329,7 @@ var __webpack_modules__ = { ] : [] ].includes(whenBusy)) throw new RangeError("--when-busy must be reject, queue, or persistent steer"); if (whenBusy === "steer" && (typeof expectedTurnId !== "string" || !ID_PATTERN.test(expectedTurnId))) throw new RangeError("steer requires expectedTurnId"); - if (typeof threadId !== "string" || !ID_PATTERN.test(threadId)) throw new RangeError("Invalid threadId"); + threadId = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > WS_MAX_MESSAGE_BYTES) throw new RangeError("Message must contain text within 4 MiB"); if (!envelope || typeof envelope.messageId !== "string" || !ID_PATTERN.test(envelope.messageId)) throw new RangeError("Invalid envelope messageId"); const validated = buildEnvelope({ @@ -23289,8 +23370,10 @@ var __webpack_modules__ = { }); } catch (err) { assertNotCancelled(); - if (err instanceof CodexSendError) throw err; - throw new CodexSendError(explainSendError(err, threadId).message, { + if (err instanceof CodexSendError || err instanceof _codex_remote_control_js__rspack_import_8.Rg) throw err; + const explained = explainSendError(err, threadId, env); + if (explained instanceof _codex_remote_control_js__rspack_import_8.Rg) throw explained; + throw new CodexSendError(explained.message, { delivery: err instanceof CodexRpcError ? "rejected" : err && err.delivery || "unknown", reason: err instanceof CodexRpcError ? /no rollout found|thread not found/i.test(String(err.rpc && err.rpc.message)) ? "unknown-thread" : /active writer/i.test(String(err.rpc && err.rpc.message)) ? "external-owner" : "rejected" : "transport", threadId, @@ -23515,7 +23598,11 @@ var __webpack_modules__ = { "messageId", "correlationId", "refused", - "hop" + "hop", + "hostId", + "hostName", + "hint", + "code" ]){ if (error[key] !== undefined) out[key] = error[key]; } @@ -23550,9 +23637,12 @@ var __webpack_modules__ = { var _contract_js__rspack_import_0 = __webpack_require__("./src/core/codex/contract.js"); var node_fs__rspack_import_1 = __webpack_require__("node:fs"); var _codex_bridge_js__rspack_import_2 = __webpack_require__("./src/core/codex-bridge.js"); + var _remote_control_js__rspack_import_3 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_id_js__rspack_import_4 = __webpack_require__("./src/core/codex/thread-id.js"); const ID = /^[A-Za-z0-9_.:-]{1,128}$/; const BUDGET = 4 * 1024 * 1024; function conversationId(value, name = 'threadId') { + if (name === 'threadId') return (0, _thread_id_js__rspack_import_4.SX)(value); if (typeof value !== 'string' || !ID.test(value)) throw new RangeError(`${name} must be 1-128 identifier characters`); return value; } @@ -23677,7 +23767,8 @@ var __webpack_modules__ = { if (expected !== undefined && (typeof cwd !== 'string' || (0, node_fs__rspack_import_1.realpathSync)(cwd) !== expected)) throw new Error('Codex thread cwd does not match expectedCwd'); } catch (error) { await close(); - throw error; + if (error instanceof _remote_control_js__rspack_import_3.Rg) throw error; + throw (0, _remote_control_js__rspack_import_3.R3)(error, threadId, env); } async function wait({ turnId, messageId, afterMessageId, timeoutMs = 120000, signal: waitSignal, maxOutputBytes = 1048576 }) { conversationId(turnId, 'turnId'); @@ -23984,6 +24075,260 @@ var __webpack_modules__ = { j: ()=>openCodexConversation }); }, + "./src/core/codex/remote-control.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var node_os__rspack_import_1 = __webpack_require__("node:os"); + var node_path__rspack_import_2 = __webpack_require__("node:path"); + var _thread_id_js__rspack_import_3 = __webpack_require__("./src/core/codex/thread-id.js"); + const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; + class RemoteThreadNotLoadedError1 extends Error { + constructor(threadId, hostId = null, hostName = null){ + const hostLabel = hostName ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` : hostId ? JSON.stringify(hostId) : null; + const owner = hostLabel ? `owned by remote-control host ${hostLabel}` : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + const hint = hostId ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + (hostName ? ` (${hostName})` : '') + '. SSH remoting is not implemented in this adapter.' : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; + super(`Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`); + this.name = 'RemoteThreadNotLoadedError'; + this.code = 'REMOTE_THREAD_NOT_LOADED'; + this.delivery = 'rejected'; + this.reason = 'remote-thread-not-loaded'; + this.threadId = threadId; + this.hostId = hostId; + this.hostName = hostName; + this.hint = hint; + } + } + function codexGlobalStatePath(env = process.env) { + const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); + return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); + } + function loadCodexGlobalState(env = process.env) { + let raw; + try { + raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); + } catch { + return null; + } + try { + const data = JSON.parse(raw); + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + return data; + } catch { + return null; + } + } + function findRemoteThreadHost(threadId, env = process.env) { + let bare; + try { + bare = (0, _thread_id_js__rspack_import_3.SX)(threadId); + } catch { + bare = typeof threadId === 'string' && threadId.startsWith("local:") ? threadId.slice("local:".length) : threadId; + } + if (!bare) return null; + const data = loadCodexGlobalState(env); + if (!data) return null; + const hostNames = collectHostNames(data); + for (const [key, value] of Object.entries(data)){ + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match?.[1]) continue; + const hostId = match[1]; + const hostName = hostNames.get(hostId) ?? extractHostName(value) ?? null; + for (const entry of extractThreadEntries(value)){ + const id = threadIdFromEntry(entry); + if (!id) continue; + const entryBare = id.startsWith("local:") ? id.slice("local:".length) : id; + if (entryBare === bare) return { + hostId, + hostName + }; + } + } + return null; + } + function mapRemoteThreadError(error, threadId, env = process.env) { + const message = errorMessage(error); + if (!/thread not loaded|not loaded|no rollout found|thread not found|invalid thread id/i.test(message)) { + return error instanceof Error ? error : new Error(message || String(error)); + } + const remote = findRemoteThreadHost(threadId, env); + if (remote) { + return new RemoteThreadNotLoadedError1(threadId, remote.hostId, remote.hostName); + } + if (/thread not loaded|not loaded/i.test(message)) { + return new RemoteThreadNotLoadedError1(threadId, null, null); + } + return error instanceof Error ? error : new Error(message || String(error)); + } + function collectHostNames(data) { + const names = new Map(); + for (const [key, value] of Object.entries(data)){ + if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; + if (!value || typeof value !== 'object') continue; + if (Array.isArray(value)) { + for (const entry of value){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + continue; + } + for (const [hostId, entry] of Object.entries(value)){ + const fromEntry = hostNameFromEntry(entry); + if (fromEntry) { + names.set(fromEntry.hostId, fromEntry.hostName); + continue; + } + const label = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (label) names.set(hostId, label); + } + } + return names; + } + function hostNameFromEntry(entry) { + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + const hostId = stringField(entry, [ + 'hostId', + 'id', + 'host_id', + 'uuid' + ]); + const hostName = stringField(entry, [ + 'name', + 'hostName', + 'displayName', + 'envName', + 'label', + 'title' + ]); + if (!hostId || !hostName) return null; + return { + hostId, + hostName + }; + } + function extractHostName(value) { + if (!value || typeof value !== 'object' || Array.isArray(value)) return null; + return stringField(value, [ + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName' + ]); + } + function extractThreadEntries(value) { + if (Array.isArray(value)) return value; + if (!value || typeof value !== 'object') return []; + const record = value; + for (const key of [ + 'threads', + 'summaries', + 'items', + 'data', + 'conversations' + ]){ + if (Array.isArray(record[key])) return record[key]; + } + const entries = []; + for (const [key, entry] of Object.entries(record)){ + if ([ + 'pinnedIds', + 'pinned', + 'pinnedThreadIds', + 'hostName', + 'displayName', + 'name', + 'envName', + 'label', + 'title', + 'friendlyName', + 'hostId', + 'version' + ].includes(key)) continue; + if (typeof entry === 'string') continue; + if (entry && typeof entry === 'object' && !Array.isArray(entry)) { + const id = stringField(entry, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]); + entries.push(id ? entry : { + ...entry, + id: key + }); + } + } + return entries; + } + function threadIdFromEntry(entry) { + if (typeof entry === 'string' && entry) return entry; + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + return stringField(entry, [ + 'id', + 'threadId', + 'thread_id', + 'conversationId' + ]); + } + function stringField(row, keys) { + if (!row || typeof row !== 'object' || Array.isArray(row)) return null; + for (const key of keys){ + const value = row[key]; + if (typeof value === 'string' && value.trim()) return value.trim(); + } + return null; + } + function errorMessage(error) { + if (!error) return ''; + if (typeof error === 'string') return error; + if (error instanceof Error) return error.message; + if (typeof error === 'object' && error && 'message' in error) return String(error.message); + if (typeof error === 'object' && error && 'rpc' in error) { + const rpc = error.rpc; + if (rpc && typeof rpc.message === 'string') return rpc.message; + } + return String(error); + } + __webpack_require__.d(__webpack_exports__, { + R3: ()=>mapRemoteThreadError, + Rg: ()=>RemoteThreadNotLoadedError1 + }); + }, + "./src/core/codex/thread-id.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { + const LOCAL_THREAD_ID_PREFIX = 'local:'; + const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; + const ID_PATTERN = /^[A-Za-z0-9_.:-]{1,128}$/; + function isTemporaryDesktopThreadId(threadId) { + return typeof threadId === 'string' && threadId.startsWith(TEMP_THREAD_ID_PREFIX); + } + function normalizeCodexThreadId1(threadId) { + if (typeof threadId !== 'string' || !threadId) { + throw new RangeError('Invalid threadId'); + } + if (isTemporaryDesktopThreadId(threadId)) { + throw new RangeError('Temporary Desktop thread id ' + JSON.stringify(threadId) + ' has no app-server mapping; wait for the real conversation id'); + } + const bare = threadId.startsWith(LOCAL_THREAD_ID_PREFIX) ? threadId.slice(LOCAL_THREAD_ID_PREFIX.length) : threadId; + if (!bare || !ID_PATTERN.test(bare)) { + throw new RangeError('Invalid threadId'); + } + return bare; + } + function hasLocalThreadPrefix(threadId) { + return typeof threadId === 'string' && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) && !isTemporaryDesktopThreadId(threadId); + } + __webpack_require__.d(__webpack_exports__, { + SX: ()=>normalizeCodexThreadId1 + }); + }, "./src/core/desktop-shim.js" (__unused_rspack___webpack_module__, __unused_rspack___webpack_exports__, __webpack_require__) { var node_child_process__rspack_import_0 = __webpack_require__("node:child_process"); var node_fs__rspack_import_1 = __webpack_require__("node:fs"); diff --git a/src/cli/codex/list-threads.tsx b/src/cli/codex/list-threads.tsx index 60949b5..81588e3 100644 --- a/src/cli/codex/list-threads.tsx +++ b/src/cli/codex/list-threads.tsx @@ -8,13 +8,14 @@ import { formatCodexThread } from '../../core/format.js'; import { failureDocumentSchema } from '../_shared.js'; export const config = { - description: 'List Codex daemon-managed threads.', + description: + 'List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).', exitCode: 'result', inputJsonSchema: { additionalProperties: false, properties: { cursor: { - description: 'Opaque pagination cursor (may start with -)', + description: 'Opaque pagination cursor from a previous nextCursor (may start with -)', type: 'string', }, limit: { default: 20, description: 'Max threads to list (1-200)', type: 'number' }, @@ -33,6 +34,7 @@ export const resultSchema = z.union([ limit: z.number().int().min(1).max(200), nextCursor: z.string().nullable(), threads: z.array(z.record(z.string(), z.json())), + useStateDbOnly: z.boolean().optional(), }).strict(), failureDocumentSchema, ]); diff --git a/src/core/chatgpt-desktop/errors.ts b/src/core/chatgpt-desktop/errors.ts index 6346f79..d00dc93 100644 --- a/src/core/chatgpt-desktop/errors.ts +++ b/src/core/chatgpt-desktop/errors.ts @@ -1,3 +1,5 @@ +import { RemoteThreadNotLoadedError as SharedRemoteThreadNotLoadedError } from '../codex/remote-control.js'; + /** Typed failure when a ChatGPT Desktop CDP/DOM operation is not yet implemented. */ export class NotImplementedError extends Error { readonly code = 'NOT_IMPLEMENTED' as const; @@ -43,43 +45,23 @@ export class CdpUnreachableError extends Error { /** * Thread exists on a remote-control host and is not loaded on the local - * app-server. SSH remoting is a follow-up — this error names the owner and - * tells the caller to read via that host's app-server. + * app-server. Shared with codex send/read paths. */ -export class RemoteThreadNotLoadedError extends Error { - readonly code = 'REMOTE_THREAD_NOT_LOADED' as const; - readonly delivery = 'rejected' as const; - readonly reason = 'remote-thread-not-loaded' as const; - readonly threadId: string; - readonly hostId: string | null; - readonly hostName: string | null; - readonly hint: string; +export class RemoteThreadNotLoadedError extends SharedRemoteThreadNotLoadedError { + declare readonly code: 'REMOTE_THREAD_NOT_LOADED'; + declare readonly delivery: 'rejected'; + declare readonly reason: 'remote-thread-not-loaded'; + declare readonly threadId: string; + declare readonly hostId: string | null; + declare readonly hostName: string | null; + declare readonly hint: string; constructor( threadId: string, hostId: string | null = null, hostName: string | null = null, ) { - const hostLabel = hostName - ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` - : hostId - ? JSON.stringify(hostId) - : null; - const owner = hostLabel - ? `owned by remote-control host ${hostLabel}` - : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; - const hint = hostId - ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + - (hostName ? ` (${hostName})` : '') + - '. SSH remoting is not implemented in this adapter.' - : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; - super( - `Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`, - ); + super(threadId, hostId, hostName); this.name = 'RemoteThreadNotLoadedError'; - this.threadId = threadId; - this.hostId = hostId; - this.hostName = hostName; - this.hint = hint; } } diff --git a/src/core/chatgpt-desktop/thread-ids.ts b/src/core/chatgpt-desktop/thread-ids.ts index 30b85cd..bcaf880 100644 --- a/src/core/chatgpt-desktop/thread-ids.ts +++ b/src/core/chatgpt-desktop/thread-ids.ts @@ -9,16 +9,23 @@ * first reply annotates a real conversation id — they do not map to app-server. */ -import { TEMP_THREAD_ID_PREFIX } from './cdp-dom.js'; +import { + LOCAL_THREAD_ID_PREFIX as SHARED_LOCAL_PREFIX, + TEMP_THREAD_ID_PREFIX as SHARED_TEMP_PREFIX, + isTemporaryDesktopThreadId as sharedIsTemporary, + normalizeCodexThreadId, +} from '../codex/thread-id.js'; +import { TEMP_THREAD_ID_PREFIX as CDP_TEMP_PREFIX } from './cdp-dom.js'; -export const LOCAL_THREAD_ID_PREFIX = 'local:' as const; +export const LOCAL_THREAD_ID_PREFIX = SHARED_LOCAL_PREFIX; +export const TEMP_THREAD_ID_PREFIX = CDP_TEMP_PREFIX; /** DOM `data-turn-key` prefix; app-server turn ids are the trailing segment. */ export const HISTORY_CONTENT_TURN_PREFIX = 'history-content:turn:' as const; /** True when the id is a transient sidebar row, not a durable conversation. */ export function isTemporaryDesktopThreadId(threadId: string): boolean { - return threadId.startsWith(TEMP_THREAD_ID_PREFIX); + return sharedIsTemporary(threadId) || threadId.startsWith(SHARED_TEMP_PREFIX); } /** @@ -27,11 +34,11 @@ export function isTemporaryDesktopThreadId(threadId: string): boolean { */ export function toAppServerThreadId(threadId: string): string | null { if (!threadId || isTemporaryDesktopThreadId(threadId)) return null; - if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) { - const bare = threadId.slice(LOCAL_THREAD_ID_PREFIX.length); - return bare || null; + try { + return normalizeCodexThreadId(threadId); + } catch { + return null; } - return threadId; } /** Require a bare app-server id; throws when the input cannot be mapped. */ diff --git a/src/core/codex-bridge.js b/src/core/codex-bridge.js index d7a79c9..0ac69cb 100644 --- a/src/core/codex-bridge.js +++ b/src/core/codex-bridge.js @@ -7,10 +7,14 @@ import { spawnSync } from "node:child_process"; import pkg from "../../package.json" with { type: "json" }; import { outcomeFromError, outcomeFromReceipt, withStatusExitCode } from "./codex/contract.js"; +import { mapRemoteThreadError, RemoteThreadNotLoadedError } from "./codex/remote-control.js"; +import { normalizeCodexThreadId } from "./codex/thread-id.js"; import { desktopShimStatus } from "./desktop-shim.js"; import { looksLikeGrokBotBox, USER_MACHINE_CODEX_CLAUDE_GUIDANCE } from "./user-machine-guidance.js"; export { looksLikeGrokBotBox } from "./user-machine-guidance.js"; +export { RemoteThreadNotLoadedError } from "./codex/remote-control.js"; +export { normalizeCodexThreadId, isTemporaryDesktopThreadId, LOCAL_THREAD_ID_PREFIX } from "./codex/thread-id.js"; // Method and param names below come from `codex app-server generate-json-schema` // of this Codex release. Newer daemons usually keep them; `gbot codex status` @@ -878,29 +882,51 @@ export async function listCodexThreads({ try { // Default daemon filter is the current provider only. Pass modelProviders: [] for // every provider, or a non-empty list to restrict. useStateDbOnly avoids a cold - // rollout rescan (tens of seconds). - const params = { + // rollout rescan (tens of seconds); fall back to a full scan when the state DB + // returns nothing on the first page. + const baseParams = { limit, - useStateDbOnly: true, modelProviders, ...(cursor !== undefined ? { cursor } : {}), }; let out; + let usedStateDbOnly = true; try { - out = await client.request("thread/list", params); + out = await client.request("thread/list", { ...baseParams, useStateDbOnly: true }); } catch (err) { throw transportError(err); } if (!isObject(out) || !Array.isArray(out.data)) throw new CodexProtocolError("thread/list", "missing `data` array"); + if ( + out.data.length === 0 + && cursor === undefined + && (out.nextCursor == null || out.nextCursor === "") + ) { + try { + out = await client.request("thread/list", { ...baseParams, useStateDbOnly: false }); + usedStateDbOnly = false; + } catch (err) { + throw transportError(err); + } + if (!isObject(out) || !Array.isArray(out.data)) throw new CodexProtocolError("thread/list", "missing `data` array"); + } if (out.nextCursor != null && typeof out.nextCursor !== "string") throw new CodexProtocolError("thread/list", "`nextCursor` is not a string"); const threads = out.data.map(summarizeThread); - return { threads, nextCursor: out.nextCursor ?? null, limit }; + return { + threads, + nextCursor: out.nextCursor ?? null, + limit, + useStateDbOnly: usedStateDbOnly, + }; } finally { client.close(); } } -function explainSendError(err, threadId) { +function explainSendError(err, threadId, env = process.env) { + if (err instanceof RemoteThreadNotLoadedError) return err; + const mapped = mapRemoteThreadError(err, threadId, env); + if (mapped instanceof RemoteThreadNotLoadedError) return mapped; if (!(err instanceof CodexRpcError)) return err; const msg = String(err.rpc && err.rpc.message || ""); if (/no rollout found|thread not found/i.test(msg)) { @@ -980,11 +1006,15 @@ export function withEnvelopeHeader(text, envelope, env = process.env) { export function assertThreadAllowed(threadId, env = process.env) { const raw = env.GROK_BOT_CODEX_THREADS; if (raw == null || raw.trim() === "") return; - const allowed = raw.split(",").map((s) => s.trim()).filter(Boolean); - if (!allowed.includes(threadId)) { + const bare = normalizeCodexThreadId(threadId); + const allowed = raw.split(",").map((s) => { + try { return normalizeCodexThreadId(s.trim()); } + catch { return s.trim(); } + }).filter(Boolean); + if (!allowed.includes(bare)) { throw new CodexSendError( - "Codex thread " + threadId + " is not in GROK_BOT_CODEX_THREADS; the operator allows only: " + allowed.join(", "), - { delivery: "rejected", reason: "route-not-allowed", threadId }, + "Codex thread " + bare + " is not in GROK_BOT_CODEX_THREADS; the operator allows only: " + allowed.join(", "), + { delivery: "rejected", reason: "route-not-allowed", threadId: bare }, ); } } @@ -1040,6 +1070,7 @@ function unsupportedOrRpc(err, method, threadId, envelope, turnId) { /** Read the daemon's queue for one thread (experimental `thread/queue/list`). */ export async function listCodexQueue(threadId, { env = process.env, limit = 50, cursor } = {}) { requireExperimental(env, "gbot codex queue"); + threadId = normalizeCodexThreadId(threadId); const { client } = await openSession(env, { experimental: true }); try { let out; @@ -1063,6 +1094,64 @@ export async function listCodexQueue(threadId, { env = process.env, limit = 50, } } +/** + * Read a thread's history without `thread/resume` and without deprecated + * `includeTurns` on `thread/read`. Metadata via `thread/read`, turns via + * paginated `thread/turns/list` (`itemsView: "full"`). + * + * @param {string} threadId + * @param {{ limit?: number, env?: NodeJS.ProcessEnv }} [opts] + */ +export async function readCodexThread(threadId, { limit = 100, env = process.env } = {}) { + if (!Number.isInteger(limit) || limit < 1 || limit > 2000) { + throw new RangeError("limit must be an integer 1-2000"); + } + const bare = normalizeCodexThreadId(threadId); + const { client } = await openSession(env); + try { + let meta; + try { + // Metadata only — never pass includeTurns (deprecated for paginated threads). + meta = await client.request("thread/read", { threadId: bare }); + } catch (err) { + const mapped = explainSendError(err, bare, env); + if (mapped instanceof RemoteThreadNotLoadedError) throw mapped; + throw transportError(err); + } + const turns = []; + let cursor; + for (let page = 0; page < 40 && turns.length < limit; page++) { + let out; + try { + out = await client.request("thread/turns/list", { + threadId: bare, + limit: Math.min(100, limit - turns.length), + itemsView: "full", + ...(cursor !== undefined ? { cursor } : {}), + }); + } catch (err) { + const mapped = explainSendError(err, bare, env); + if (mapped instanceof RemoteThreadNotLoadedError) throw mapped; + throw transportError(err); + } + if (!isObject(out) || !Array.isArray(out.data)) { + throw new CodexProtocolError("thread/turns/list", "missing `data` array"); + } + for (const row of out.data) turns.push(row); + if (out.nextCursor == null || typeof out.nextCursor !== "string") break; + cursor = out.nextCursor; + } + return { + threadId: bare, + thread: isObject(meta) && isObject(meta.thread) ? meta.thread : null, + turns: turns.slice(0, limit), + nextCursor: cursor ?? null, + }; + } finally { + client.close(); + } +} + /** * @param {string} threadId * @param {string} text @@ -1085,7 +1174,7 @@ export async function sendToCodexThread(threadId, text, { env = process.env, env async function sendToCodexThreadInner(threadId, text, { env, envelope, whenBusy, session, expectedTurnId, expectedCwd, signal }) { if (!["reject", "queue", ...(session ? ["steer"] : [])].includes(whenBusy)) throw new RangeError("--when-busy must be reject, queue, or persistent steer"); if (whenBusy === "steer" && (typeof expectedTurnId !== "string" || !ID_PATTERN.test(expectedTurnId))) throw new RangeError("steer requires expectedTurnId"); - if (typeof threadId !== "string" || !ID_PATTERN.test(threadId)) throw new RangeError("Invalid threadId"); + threadId = normalizeCodexThreadId(threadId); if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > WS_MAX_MESSAGE_BYTES) throw new RangeError("Message must contain text within 4 MiB"); if (!envelope || typeof envelope.messageId !== "string" || !ID_PATTERN.test(envelope.messageId)) throw new RangeError("Invalid envelope messageId"); const validated = buildEnvelope({ correlationId: envelope.correlationId, replyTo: envelope.replyTo, hop: envelope.hop, env }); @@ -1107,8 +1196,10 @@ async function sendToCodexThreadInner(threadId, text, { env, envelope, whenBusy, resumed = await client.request("thread/resume", { threadId, excludeTurns: true }); } catch (err) { assertNotCancelled(); - if (err instanceof CodexSendError) throw err; - throw new CodexSendError(explainSendError(err, threadId).message, { + if (err instanceof CodexSendError || err instanceof RemoteThreadNotLoadedError) throw err; + const explained = explainSendError(err, threadId, env); + if (explained instanceof RemoteThreadNotLoadedError) throw explained; + throw new CodexSendError(explained.message, { delivery: err instanceof CodexRpcError ? "rejected" : (err && err.delivery) || "unknown", reason: err instanceof CodexRpcError ? (/no rollout found|thread not found/i.test(String(err.rpc && err.rpc.message)) ? "unknown-thread" : /active writer/i.test(String(err.rpc && err.rpc.message)) ? "external-owner" : "rejected") : "transport", diff --git a/src/core/codex/contract.js b/src/core/codex/contract.js index 7dee301..af8f0b9 100644 --- a/src/core/codex/contract.js +++ b/src/core/codex/contract.js @@ -81,7 +81,10 @@ export function outcomeFromError(error, opts = {}) { const out = { error: message }; if (error && typeof error === "object") { - for (const key of ["delivery", "reason", "mode", "threadId", "turnId", "targetId", "messageId", "correlationId", "refused", "hop"]) { + for (const key of [ + "delivery", "reason", "mode", "threadId", "turnId", "targetId", "messageId", + "correlationId", "refused", "hop", "hostId", "hostName", "hint", "code", + ]) { if (error[key] !== undefined) out[key] = error[key]; } if (out.reason === undefined && isUsage(error)) out.reason = "usage"; diff --git a/src/core/codex/conversation.js b/src/core/codex/conversation.js index 20ee9e7..1ddbf9d 100644 --- a/src/core/codex/conversation.js +++ b/src/core/codex/conversation.js @@ -1,10 +1,13 @@ import { outcomeFromError } from './contract.js'; import { realpathSync } from 'node:fs'; import { assertThreadAllowed, buildEnvelope, experimentalEnabled, openCodexSession, sendToCodexThread } from '../codex-bridge.js'; +import { mapRemoteThreadError, RemoteThreadNotLoadedError } from './remote-control.js'; +import { normalizeCodexThreadId } from './thread-id.js'; const ID = /^[A-Za-z0-9_.:-]{1,128}$/; const BUDGET = 4 * 1024 * 1024; function conversationId(value, name = 'threadId') { + if (name === 'threadId') return normalizeCodexThreadId(value); if (typeof value !== 'string' || !ID.test(value)) throw new RangeError(`${name} must be 1-128 identifier characters`); return value; } @@ -79,7 +82,11 @@ export async function openCodexConversation(threadId, options = {}) { if (resumed?.thread?.id !== threadId) throw new Error('thread/resume returned a different thread ID'); const cwd = resumed.cwd ?? resumed.thread.cwd; if (expected !== undefined && (typeof cwd !== 'string' || realpathSync(cwd) !== expected)) throw new Error('Codex thread cwd does not match expectedCwd'); - } catch (error) { await close(); throw error; } + } catch (error) { + await close(); + if (error instanceof RemoteThreadNotLoadedError) throw error; + throw mapRemoteThreadError(error, threadId, env); + } /** @param {{turnId: string, messageId?: string, afterMessageId?: string|string[], timeoutMs?: number, signal?: AbortSignal, maxOutputBytes?: number}} options */ async function wait({ turnId, messageId, afterMessageId, timeoutMs = 120000, signal: waitSignal, maxOutputBytes = 1048576 }) { diff --git a/src/core/codex/remote-control.js b/src/core/codex/remote-control.js new file mode 100644 index 0000000..a68799d --- /dev/null +++ b/src/core/codex/remote-control.js @@ -0,0 +1,224 @@ +/** + * Remote-control thread ownership from ChatGPT Desktop's + * `~/.codex/.codex-global-state.json` (`remote-thread-summaries-v3:`). + * + * Shared by codex-bridge send/read and the ChatGPT Desktop adapter so both + * surfaces map "thread not loaded" to the same typed error. + */ + +import { readFileSync } from 'node:fs'; +import { homedir } from 'node:os'; +import { join } from 'node:path'; + +import { LOCAL_THREAD_ID_PREFIX, normalizeCodexThreadId } from './thread-id.js'; + +const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; + +/** + * Thread exists on a remote-control host and is not loaded on the local + * app-server. SSH remoting is a follow-up — this error names the owner. + */ +export class RemoteThreadNotLoadedError extends Error { + /** + * @param {string} threadId + * @param {string | null} [hostId] + * @param {string | null} [hostName] + */ + constructor(threadId, hostId = null, hostName = null) { + const hostLabel = hostName + ? `${JSON.stringify(hostName)} (${JSON.stringify(hostId)})` + : hostId + ? JSON.stringify(hostId) + : null; + const owner = hostLabel + ? `owned by remote-control host ${hostLabel}` + : 'owned by a remote-control host (hostId unknown; check ~/.codex/.codex-global-state.json)'; + const hint = hostId + ? `Read this thread via host ${JSON.stringify(hostId)}'s app-server` + + (hostName ? ` (${hostName})` : '') + + '. SSH remoting is not implemented in this adapter.' + : "Read this thread via the owning host's app-server. SSH remoting is not implemented in this adapter."; + super( + `Codex thread ${JSON.stringify(threadId)} is not loaded on the local app-server; ${owner}. ${hint}`, + ); + this.name = 'RemoteThreadNotLoadedError'; + this.code = 'REMOTE_THREAD_NOT_LOADED'; + this.delivery = 'rejected'; + this.reason = 'remote-thread-not-loaded'; + this.threadId = threadId; + this.hostId = hostId; + this.hostName = hostName; + this.hint = hint; + } +} + +export function codexGlobalStatePath(env = process.env) { + const home = env.CODEX_HOME || join(homedir(), '.codex'); + return join(home, '.codex-global-state.json'); +} + +/** @returns {Record | null} */ +export function loadCodexGlobalState(env = process.env) { + let raw; + try { + raw = readFileSync(codexGlobalStatePath(env), 'utf8'); + } catch { + return null; + } + try { + const data = JSON.parse(raw); + if (!data || typeof data !== 'object' || Array.isArray(data)) return null; + return data; + } catch { + return null; + } +} + +/** + * @param {string} threadId + * @param {NodeJS.ProcessEnv} [env] + * @returns {{ hostId: string, hostName: string | null } | null} + */ +export function findRemoteThreadHost(threadId, env = process.env) { + let bare; + try { + bare = normalizeCodexThreadId(threadId); + } catch { + bare = typeof threadId === 'string' && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) + ? threadId.slice(LOCAL_THREAD_ID_PREFIX.length) + : threadId; + } + if (!bare) return null; + const data = loadCodexGlobalState(env); + if (!data) return null; + const hostNames = collectHostNames(data); + + for (const [key, value] of Object.entries(data)) { + const match = REMOTE_SUMMARY_KEY.exec(key); + if (!match?.[1]) continue; + const hostId = match[1]; + const hostName = hostNames.get(hostId) ?? extractHostName(value) ?? null; + for (const entry of extractThreadEntries(value)) { + const id = threadIdFromEntry(entry); + if (!id) continue; + const entryBare = id.startsWith(LOCAL_THREAD_ID_PREFIX) + ? id.slice(LOCAL_THREAD_ID_PREFIX.length) + : id; + if (entryBare === bare) return { hostId, hostName }; + } + } + return null; +} + +/** + * Map app-server "thread not loaded" / unknown-thread errors to a typed remote + * error when the id appears under remote-control summaries. + * @param {unknown} error + * @param {string} threadId + * @param {NodeJS.ProcessEnv} [env] + * @returns {Error} + */ +export function mapRemoteThreadError(error, threadId, env = process.env) { + const message = errorMessage(error); + if (!/thread not loaded|not loaded|no rollout found|thread not found|invalid thread id/i.test(message)) { + return error instanceof Error ? error : new Error(message || String(error)); + } + const remote = findRemoteThreadHost(threadId, env); + if (remote) { + return new RemoteThreadNotLoadedError(threadId, remote.hostId, remote.hostName); + } + // "thread not loaded" without a known remote host still gets a typed hint. + if (/thread not loaded|not loaded/i.test(message)) { + return new RemoteThreadNotLoadedError(threadId, null, null); + } + return error instanceof Error ? error : new Error(message || String(error)); +} + +function collectHostNames(data) { + const names = new Map(); + for (const [key, value] of Object.entries(data)) { + if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; + if (!value || typeof value !== 'object') continue; + if (Array.isArray(value)) { + for (const entry of value) { + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + continue; + } + for (const [hostId, entry] of Object.entries(value)) { + const fromEntry = hostNameFromEntry(entry); + if (fromEntry) { + names.set(fromEntry.hostId, fromEntry.hostName); + continue; + } + const label = stringField(entry, ['name', 'hostName', 'displayName', 'envName', 'label', 'title']); + if (label) names.set(hostId, label); + } + } + return names; +} + +function hostNameFromEntry(entry) { + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + const hostId = stringField(entry, ['hostId', 'id', 'host_id', 'uuid']); + const hostName = stringField(entry, ['name', 'hostName', 'displayName', 'envName', 'label', 'title']); + if (!hostId || !hostName) return null; + return { hostId, hostName }; +} + +function extractHostName(value) { + if (!value || typeof value !== 'object' || Array.isArray(value)) return null; + return stringField(value, [ + 'hostName', 'displayName', 'name', 'envName', 'label', 'title', 'friendlyName', + ]); +} + +function extractThreadEntries(value) { + if (Array.isArray(value)) return value; + if (!value || typeof value !== 'object') return []; + const record = value; + for (const key of ['threads', 'summaries', 'items', 'data', 'conversations']) { + if (Array.isArray(record[key])) return record[key]; + } + const entries = []; + for (const [key, entry] of Object.entries(record)) { + if ([ + 'pinnedIds', 'pinned', 'pinnedThreadIds', 'hostName', 'displayName', 'name', + 'envName', 'label', 'title', 'friendlyName', 'hostId', 'version', + ].includes(key)) continue; + if (typeof entry === 'string') continue; + if (entry && typeof entry === 'object' && !Array.isArray(entry)) { + const id = stringField(entry, ['id', 'threadId', 'thread_id', 'conversationId']); + entries.push(id ? entry : { ...entry, id: key }); + } + } + return entries; +} + +function threadIdFromEntry(entry) { + if (typeof entry === 'string' && entry) return entry; + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null; + return stringField(entry, ['id', 'threadId', 'thread_id', 'conversationId']); +} + +function stringField(row, keys) { + if (!row || typeof row !== 'object' || Array.isArray(row)) return null; + for (const key of keys) { + const value = row[key]; + if (typeof value === 'string' && value.trim()) return value.trim(); + } + return null; +} + +function errorMessage(error) { + if (!error) return ''; + if (typeof error === 'string') return error; + if (error instanceof Error) return error.message; + if (typeof error === 'object' && error && 'message' in error) return String(error.message); + if (typeof error === 'object' && error && 'rpc' in error) { + const rpc = error.rpc; + if (rpc && typeof rpc.message === 'string') return rpc.message; + } + return String(error); +} diff --git a/src/core/codex/routes.ts b/src/core/codex/routes.ts index 9ab64e3..e110d74 100644 --- a/src/core/codex/routes.ts +++ b/src/core/codex/routes.ts @@ -2,8 +2,21 @@ import { z } from 'zod'; import { buildEnvelope, listCodexThreads, sendToCodexThread } from '../codex-bridge.js'; import { outcomeFromError } from './contract.js'; import { openCodexConversation } from './conversation.js'; +import { normalizeCodexThreadId } from './thread-id.js'; -const id = z.string().regex(/^[A-Za-z0-9_.:-]{1,128}$/); +const bareId = z.string().regex(/^[A-Za-z0-9_.:-]{1,128}$/); +/** Accept Desktop `local:` and normalize before the bare-id check. */ +const id = z.string().min(1).max(160).transform((value, ctx) => { + try { + return normalizeCodexThreadId(value); + } catch (error) { + ctx.addIssue({ + code: 'custom', + message: error instanceof Error ? error.message : 'Invalid threadId', + }); + return z.NEVER; + } +}).pipe(bareId); export const observationFields = { expectedCwd: z.string().min(1).optional(), threadId: id, diff --git a/src/core/codex/thread-id.js b/src/core/codex/thread-id.js new file mode 100644 index 0000000..565c0c9 --- /dev/null +++ b/src/core/codex/thread-id.js @@ -0,0 +1,47 @@ +/** + * Normalize Desktop sidebar thread ids for Codex app-server RPCs. + * + * ChatGPT Desktop sidebar rows use `local:`. App-server rejects + * the prefixed form with `invalid thread id`. Temporary composer rows + * (`local:client-new-thread:…`) have no app-server mapping. + */ + +export const LOCAL_THREAD_ID_PREFIX = 'local:'; +export const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; + +const ID_PATTERN = /^[A-Za-z0-9_.:-]{1,128}$/; + +export function isTemporaryDesktopThreadId(threadId) { + return typeof threadId === 'string' && threadId.startsWith(TEMP_THREAD_ID_PREFIX); +} + +/** + * Strip a leading `local:` prefix. Temporary Desktop rows throw. + * @param {string} threadId + * @returns {string} + */ +export function normalizeCodexThreadId(threadId) { + if (typeof threadId !== 'string' || !threadId) { + throw new RangeError('Invalid threadId'); + } + if (isTemporaryDesktopThreadId(threadId)) { + throw new RangeError( + 'Temporary Desktop thread id ' + JSON.stringify(threadId) + + ' has no app-server mapping; wait for the real conversation id', + ); + } + const bare = threadId.startsWith(LOCAL_THREAD_ID_PREFIX) + ? threadId.slice(LOCAL_THREAD_ID_PREFIX.length) + : threadId; + if (!bare || !ID_PATTERN.test(bare)) { + throw new RangeError('Invalid threadId'); + } + return bare; +} + +/** True when the value looks like a Desktop-prefixed durable id. */ +export function hasLocalThreadPrefix(threadId) { + return typeof threadId === 'string' + && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) + && !isTemporaryDesktopThreadId(threadId); +} diff --git a/src/mcp/grok-bot/tools/codex_threads.tsx b/src/mcp/grok-bot/tools/codex_threads.tsx index a7b5100..7350eca 100644 --- a/src/mcp/grok-bot/tools/codex_threads.tsx +++ b/src/mcp/grok-bot/tools/codex_threads.tsx @@ -10,10 +10,11 @@ export default defineTool({ inputJsonSchema: { type: 'object', additionalProperties: false, properties: { "limit": { "type": "number", - "description": "Maximum threads in this page: 1-200." + "description": "Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page." }, "cursor": { - "type": "string" + "type": "string", + "description": "Opaque nextCursor from a previous page." } }, required: [] }, }, async input => { diff --git a/test/codex-bridge.test.js b/test/codex-bridge.test.js index 7aa0b22..6815d06 100644 --- a/test/codex-bridge.test.js +++ b/test/codex-bridge.test.js @@ -148,6 +148,7 @@ test("codex list-threads passes --limit and prints threads", async () => { ], nextCursor: null, limit: 20, + useStateDbOnly: true, exitCode: 0, }); assert.deepEqual(fake.received.at(-1).params, { @@ -1522,3 +1523,150 @@ for (const whenBusy of ["reject", "queue"]) { } }); } + +test("codex list-threads falls back to a full scan when useStateDbOnly returns nothing", async () => { + const seen = []; + const fake = await fakeAppServer({ + ...baseHandlers, + "thread/list": (params, ok) => { + seen.push(params); + if (params.useStateDbOnly) return ok({ data: [], nextCursor: null }); + ok({ data: [THREADS[0]], nextCursor: null }); + }, + }); + try { + const { code, out } = await gbot(fake.home, "codex", "list-threads", "--json"); + assert.equal(code, 0, out); + const page = JSON.parse(out); + assert.deepEqual(page.threads.map((t) => t.id), ["t-1"]); + assert.equal(page.useStateDbOnly, false); + assert.deepEqual(seen, [ + { limit: 20, modelProviders: [], useStateDbOnly: true }, + { limit: 20, modelProviders: [], useStateDbOnly: false }, + ]); + } finally { + await fake.close(); + } +}); + +test("codex send strips a Desktop local: thread id prefix before resume", async () => { + const fake = await fakeAppServer(baseHandlers); + try { + const { code, out } = await gbot( + fake.home, + "codex", + "send", + "local:t-1", + "hello", + "--json", + ); + assert.equal(code, 0, out); + const receipt = JSON.parse(out); + assert.equal(receipt.threadId, "t-1"); + const resume = fake.received.find((m) => m.method === "thread/resume"); + assert.deepEqual(resume.params, { threadId: "t-1", excludeTurns: true }); + const start = fake.received.find((m) => m.method === "turn/start"); + assert.equal(start.params.threadId, "t-1"); + } finally { + await fake.close(); + } +}); + +test("codex send maps remote-control thread not loaded to a typed host error", async () => { + const { copyFileSync } = await import("node:fs"); + const home = mkdtempSync(join(tmpdir(), "gbot-remote-send-")); + mkdirSync(home, { recursive: true }); + copyFileSync( + join(fileURLToPath(new URL(".", import.meta.url)), "../tests/fixtures/codex-global-state-remote.json"), + join(home, ".codex-global-state.json"), + ); + const fake = await fakeAppServer({ + ...baseHandlers, + "thread/resume": (params, ok, err) => + err({ code: -32600, message: "thread not loaded: " + params.threadId }), + }); + // Point CODEX_HOME at the fixture home for global-state lookup, but use the + // fake socket via CODEX_APP_SERVER_SOCK. + try { + const envHome = fake.home; + const { readFileSync, writeFileSync } = await import("node:fs"); + // Install the remote fixture into the fake home so findRemoteThreadHost sees it. + writeFileSync( + join(envHome, ".codex-global-state.json"), + readFileSync(join(home, ".codex-global-state.json")), + ); + const { code, out } = await gbot( + envHome, + "codex", + "send", + "local:aaaa1111-1111-1111-1111-111111111111", + "hi", + "--json", + ); + assert.equal(code, 1, out); + const failure = JSON.parse(out); + assert.equal(failure.reason, "remote-thread-not-loaded"); + assert.equal(failure.code, "REMOTE_THREAD_NOT_LOADED"); + assert.equal(failure.hostId, "host-macbook"); + assert.equal(failure.hostName, "Zack's MacBook"); + assert.match(failure.error, /host-macbook/); + assert.match(failure.hint, /host-macbook/); + assert.equal(failure.threadId, "aaaa1111-1111-1111-1111-111111111111"); + } finally { + await fake.close(); + } +}); + +test("readCodexThread uses thread/read without includeTurns and pages thread/turns/list", async () => { + const { readCodexThread } = await import("../src/core/codex-bridge.js"); + const seen = []; + const fake = await fakeAppServer({ + ...baseHandlers, + "thread/read": (params, ok) => { + seen.push({ method: "thread/read", params }); + ok({ thread: { id: params.threadId, name: "History", status: { type: "idle" } } }); + }, + "thread/turns/list": (params, ok) => { + seen.push({ method: "thread/turns/list", params }); + if (!params.cursor) { + return ok({ + data: [{ id: "turn-a", status: "completed", items: [] }], + nextCursor: "page-2", + }); + } + ok({ + data: [{ id: "turn-b", status: "completed", items: [] }], + nextCursor: null, + }); + }, + }); + try { + const out = await readCodexThread("local:t-1", { env: { CODEX_HOME: fake.home }, limit: 10 }); + assert.equal(out.threadId, "t-1"); + assert.equal(out.thread.name, "History"); + assert.deepEqual(out.turns.map((t) => t.id), ["turn-a", "turn-b"]); + assert.deepEqual(seen[0], { method: "thread/read", params: { threadId: "t-1" } }); + assert.equal("includeTurns" in seen[0].params, false); + assert.deepEqual(seen[1].params, { + threadId: "t-1", + limit: 10, + itemsView: "full", + }); + assert.deepEqual(seen[2].params, { + threadId: "t-1", + limit: 9, + itemsView: "full", + cursor: "page-2", + }); + } finally { + await fake.close(); + } +}); + +test("normalizeCodexThreadId strips local: and rejects temporary Desktop rows", async () => { + const { normalizeCodexThreadId, isTemporaryDesktopThreadId } = await import("../src/core/codex-bridge.js"); + assert.equal(normalizeCodexThreadId("local:abc-123"), "abc-123"); + assert.equal(normalizeCodexThreadId("abc-123"), "abc-123"); + assert.equal(isTemporaryDesktopThreadId("local:client-new-thread:x"), true); + assert.throws(() => normalizeCodexThreadId("local:client-new-thread:x"), /Temporary Desktop/); +}); diff --git a/test/host-tool-inventory.test.js b/test/host-tool-inventory.test.js index 44b82c2..74c6033 100644 --- a/test/host-tool-inventory.test.js +++ b/test/host-tool-inventory.test.js @@ -12,6 +12,7 @@ const entry = config.mcpServers['grok-bot'].args[0].replace('${CLAUDE_PLUGIN_ROO const codex = ['codex_send', 'codex_threads', 'codex_wait', 'codex_watch', 'gbot_codex_respond']; const grok = ['gbot_send', 'gbot_thread', 'gbot_grok_approvals', 'gbot_grok_respond']; const shared = [ + 'chatgpt_desktop_list_hosts', 'chatgpt_desktop_list_threads', 'chatgpt_desktop_read_thread', 'chatgpt_desktop_search_threads', From 9dfdfa36c91cc12f5245de0dbe835e61e804665e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 01:47:30 +0000 Subject: [PATCH 14/26] fix: CDP production risks from Ripwire audit Resolve new-thread send to data-response-annotation-conversation (never return local:client-new-thread:* as threadId). Harden column-reverse history wheels, Loading task timeouts, local:/bare sidebar dedupe+open, exact MAIN_WINDOW_URL attach, and keep loopback + useStateDbOnly cold-list guards covered by tests. Co-authored-by: Zack Jackson --- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 145 ++++++++++++++--- artifact/bin/gbot.mjs | 145 ++++++++++++++--- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 149 ++++++++++++++---- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 149 ++++++++++++++---- docs/chatgpt-desktop-cdp.md | 8 +- src/core/chatgpt-desktop/cdp-adapter.ts | 60 +++++-- src/core/chatgpt-desktop/cdp-dom.ts | 131 +++++++++++++-- src/core/chatgpt-desktop/index.ts | 8 + src/core/chatgpt-desktop/types.ts | 8 +- .../grok-bot/tools/chatgpt_desktop_send.tsx | 2 +- tests/route-unit/chatgpt-desktop.test.ts | 118 +++++++++++++- 13 files changed, 788 insertions(+), 139 deletions(-) diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 0977f8c..32afad4 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"59a193a8278b9fdd51fb47c4e02cc0c79c7a24fdf6d63bdaa3f44be8dcec23bf"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"9be8afe780425204731648c4555d9918b36eca3cc6dc692d202d3682c505c432"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"c2c85b5b9b1d9e3b6d6988fa4c53f60da14d44bd687ae4fc02303d22c3356c29"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"9149f1cfbd0748efe8cf327f2902b9174d27891e53083739857a51c332c3668e"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"32b2e4be3307b3971e92791b0113ffd83dcb4ba4b8167162a8c4941789481e8e"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"1d32022b7d06a39a1183f99e325713ba05270dd651c8290099a27ce13df94df6"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"346b2d02ba1d826f5520cc69f53648c1b02499f27edea9f7d61cd20a15a401a2"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b062cef72b7632a3701dec6179f88357f3b741db6c9c364a120e4de72ea5dd9f"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 8937dec..6a7fea3 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"74f3207ba9cbfe8dbb1ad36e3617745c4adab85b6fd6202a400a21d800429160","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"be5ec043449dfaad125551d0ff185947b23943c670eba78823a6ff57767959f2","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"6a8b392ec45d4a5f70ce68fa35a285c2948c72d05671b07696b9ec9b0021cb89"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"1d3d8ed8ab8fe80184eb780262b5577cb26131a7b61b7e815737e9e412d8d4e6"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"1c03ed7644b8006a00b751ea3b97630e008e5896c3797ef0f1cb510b941c6234"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"6f9facafa101776ce7ddf4282a4f19edcfc40b76da251afa59f8e2f4350c9f33"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"21454ac9c648e0d130d40d1f15f9e909cf5c82eafa018e7a066a419b72cb0d41"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"8be4849f9c85c392d3e989d222d714169da982c0337d57cdc3411d14084d9bf3"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"583279e0360f529405948a6fb33712dabaa9917bb616bd00dcc83a6b6422827c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"8a45cab48d9f02da4fa2118e0a238696ab2f4ee198faff45ac64580c1f687d3a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"98edba7908cecffb141018bc358074f2785baf84bd76c4e9564843d48ad9e2dd"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"9b35df3fa9a4a1655b9cb2e2f0d3b83e796648fc8d4ab3cacfa856f78e6a2df5"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"e8e1ba9c8d39307cdd1d849fb1f8e93c7c90421fcaa5eb8bbfdf9b579241f1be"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"694159395711268403159676c679a6a0d939bbaff546b673136f0ce4a67d686a"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"f4843da5a5fde4728e2dfe6766be0ce29b50a45af8a9508df8fcf86dffaee651"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"8463e5a981dcc4f67b386c5f1b97504905ef9a3fc7748992af8ac4e544ed0855"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"5289188da20a1b4a9561cf814e0cc20dff38c1950d291892675948debc36a610"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"6f49f1cce9590831953915a8f1f8ecc3e641bc5a1230a26f35937f257393bc26"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"dfaf2ea60ea7e46be61accc91b20e591125618c83a1910ea20ed72a75322f9d8"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4d5f799e587d8d4be6e7bacb9209816c7756605f75a0595dc3d3052f04048624"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"b7a255452eb50e8b6cc3f3f589189d3c206c47395eed2aa6504d950ca7c69ea9"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"0d2d7067c8a8538fa40c6f0a68a666e65fa7a6f06f39de359e64ff30f752db5a"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"357cd413a37f173d51cacbdb6372d41b90b4d8d44787b6a2a456c7d4f4423336"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"7f21f53f2ba99894d65b3dee8518f9483805fc2bda9444939a5a1fa44d74df30"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"c473cd9f3954480e3280ad5ed8eef7b135571c94e0ff0a3b7f825348406b762c"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"ac0af152fad9c3d01f36aaf003c8bee4cb2ea7fed022e612ce21bcfe7160a98b"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22816,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"84afcff73e067dc324f28400ea06fb3a7477bbabe7c6234f0b80ad4a40f1ccb8"},{"bytes":1515489,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"59a193a8278b9fdd51fb47c4e02cc0c79c7a24fdf6d63bdaa3f44be8dcec23bf"},{"bytes":2379440,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"9be8afe780425204731648c4555d9918b36eca3cc6dc692d202d3682c505c432"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1436022,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"c2c85b5b9b1d9e3b6d6988fa4c53f60da14d44bd687ae4fc02303d22c3356c29"},{"bytes":3262537,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"9149f1cfbd0748efe8cf327f2902b9174d27891e53083739857a51c332c3668e"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298440,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads; --host and --model-provider are separate filters.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter: all (default) | local | hostId or friendly name","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Pass-through to app-server modelProviders (omit = all)","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter: all (default) | local | hostId or friendly name","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Pass-through to app-server modelProviders (omit = all)","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads; --host and --model-provider are separate filters.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"9081e7f6af0344bb36b13c6e652b65b524c34844a9eb2207db46d24d07a4a889","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"311d86d1331309d0ab755c7c38d3b0b208c945aa30423941fe4ea4b752837337","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"6c2a2fa0d497c7e120a6adc8d3c6433535fa65ebee7577df5601543e74aaad2d","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"6a8b392ec45d4a5f70ce68fa35a285c2948c72d05671b07696b9ec9b0021cb89"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"d09018a2c8ba33d6b252a6522bb8957c5cf811c915994756126ea504747ec140"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"1c03ed7644b8006a00b751ea3b97630e008e5896c3797ef0f1cb510b941c6234"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"6f9facafa101776ce7ddf4282a4f19edcfc40b76da251afa59f8e2f4350c9f33"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"21454ac9c648e0d130d40d1f15f9e909cf5c82eafa018e7a066a419b72cb0d41"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"8be4849f9c85c392d3e989d222d714169da982c0337d57cdc3411d14084d9bf3"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"583279e0360f529405948a6fb33712dabaa9917bb616bd00dcc83a6b6422827c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"f9eb6f1333359c0523b2d4682a2ffac4dd79d0e60f5354b2e8d865443327d768"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"436567316d576e343963bcaff2086674e172bf42d4ff62a76e52e8b2d41897eb"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"9b35df3fa9a4a1655b9cb2e2f0d3b83e796648fc8d4ab3cacfa856f78e6a2df5"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"e8e1ba9c8d39307cdd1d849fb1f8e93c7c90421fcaa5eb8bbfdf9b579241f1be"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"f4843da5a5fde4728e2dfe6766be0ce29b50a45af8a9508df8fcf86dffaee651"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"8463e5a981dcc4f67b386c5f1b97504905ef9a3fc7748992af8ac4e544ed0855"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"5c8b225957262fcb281bafb82f6d89c84604fb022858737abd8cc9c8f4b5cb01"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"6f49f1cce9590831953915a8f1f8ecc3e641bc5a1230a26f35937f257393bc26"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"dfaf2ea60ea7e46be61accc91b20e591125618c83a1910ea20ed72a75322f9d8"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4d5f799e587d8d4be6e7bacb9209816c7756605f75a0595dc3d3052f04048624"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"b7a255452eb50e8b6cc3f3f589189d3c206c47395eed2aa6504d950ca7c69ea9"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"0d2d7067c8a8538fa40c6f0a68a666e65fa7a6f06f39de359e64ff30f752db5a"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"357cd413a37f173d51cacbdb6372d41b90b4d8d44787b6a2a456c7d4f4423336"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"c473cd9f3954480e3280ad5ed8eef7b135571c94e0ff0a3b7f825348406b762c"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"a33b5ff87d951e6276ec779d39392fa3050cd1ed69833accbccc9ae2576b4644"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22816,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"bbd565497cd3fd0fe527da7af6ac7a0389dce9f64944aa75ad85bc45d937b5b6"},{"bytes":1520940,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"32b2e4be3307b3971e92791b0113ffd83dcb4ba4b8167162a8c4941789481e8e"},{"bytes":2384891,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"1d32022b7d06a39a1183f99e325713ba05270dd651c8290099a27ce13df94df6"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1441603,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"346b2d02ba1d826f5520cc69f53648c1b02499f27edea9f7d61cd20a15a401a2"},{"bytes":3268118,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b062cef72b7632a3701dec6179f88357f3b741db6c9c364a120e4de72ea5dd9f"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298440,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads; --host and --model-provider are separate filters.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter: all (default) | local | hostId or friendly name","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Pass-through to app-server modelProviders (omit = all)","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter: all (default) | local | hostId or friendly name","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Pass-through to app-server modelProviders (omit = all)","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads; --host and --model-provider are separate filters.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"54c92b7e19bd37f7db8f0c939e523bc6b14a9335bc62b383590c844d4dd59b6e","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index df87b8d..001889b 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -11826,16 +11826,17 @@ var __webpack_modules__ = { var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _cdp_session_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); var _cdp_dom_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); - var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _loopback_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); class CdpChatGptDesktopAdapter { - #port = (0, _loopback_js__rspack_import_3.L0)(); + #port = (0, _loopback_js__rspack_import_4.L0)(); #session = null; #version = null; #pageSessionId = null; #mainTargetId = null; async connect({ port }) { await this.close(); - this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); const session = new _cdp_session_js__rspack_import_1.a(this.#port); try { this.#version = await session.connect(); @@ -11882,7 +11883,7 @@ var __webpack_modules__ = { async sendMessage({ threadId, text, project, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); let temporaryThreadId; - let resolvedThreadId = threadId ?? 'new'; + const startedNew = !threadId; if (threadId) { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } else { @@ -11894,15 +11895,24 @@ var __webpack_modules__ = { limit: 20 }); const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); - if (temp) { - temporaryThreadId = temp.threadId; - resolvedThreadId = temp.threadId; - } + if (temp) temporaryThreadId = temp.threadId; } const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + let conversationId; + if (startedNew || threadId && (0, _thread_ids_js__rspack_import_3.vr)(threadId)) { + const resolveMs = Math.min(openTimeoutMs, 60000); + conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { + timeoutMs: resolveMs + }); + } + const durable = (0, _cdp_dom_js__rspack_import_2.X8)(conversationId, threadId); + if (!durable) { + throw new Error('ChatGPT Desktop send accepted but no durable conversation id was available; ' + 'refusing to return a local:client-new-thread:* id as threadId'); + } return { - threadId: resolvedThreadId, + threadId: durable, temporaryThreadId, + conversationId: conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, project, backend: 'cdp', experimental: false, @@ -11913,7 +11923,7 @@ var __webpack_modules__ = { } async waitForReply({ threadId, timeoutMs = 120000 }) { const sessionId = await this.#ensurePageSession(); - if (threadId && !threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && threadId !== 'new') { + if (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) && threadId !== 'new') { try { await this.#openAndWait(sessionId, threadId, 90000); } catch {} @@ -11924,10 +11934,13 @@ var __webpack_modules__ = { timeoutMs, baselineFinalCount: baseline.finalAssistantCount }); - const resolvedId = done.conversationId || threadId || 'unknown'; + const durable = (0, _cdp_dom_js__rspack_import_2.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_3.BS)(done.conversationId) : null); + if (!durable) { + throw new Error('ChatGPT Desktop reply finished without a durable conversation id on ' + '[data-response-annotation-conversation]'); + } return { - threadId: resolvedId, - conversationId: done.conversationId || undefined, + threadId: durable, + conversationId: done.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, reply: done.reply, backend: 'cdp', experimental: false, @@ -11935,8 +11948,19 @@ var __webpack_modules__ = { }; } catch (error) { const last = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); + const durable = (0, _cdp_dom_js__rspack_import_2.X8)(last.conversationId, threadId); + if (last.reply && durable) { + return { + threadId: durable, + conversationId: last.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, + reply: last.reply, + backend: 'cdp', + experimental: false, + delivery: 'replied' + }; + } return { - threadId: last.conversationId || threadId || 'unknown', + threadId: durable ?? (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) ? threadId : 'unknown'), conversationId: last.conversationId || undefined, reply: last.reply, backend: 'cdp', @@ -12038,6 +12062,7 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_thread_id_js__rspack_import_0 = __webpack_require__("./src/core/codex/thread-id.js"); const MAIN_WINDOW_URL = 'app://-/index.html'; const IGNORED_TARGET_URL_MARKERS = [ 'initialRoute=%2Favatar-overlay', @@ -12066,8 +12091,10 @@ var __webpack_modules__ = { const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; const LOADING_TASK_TEXT = 'Loading task…'; const DEFAULT_OPEN_TIMEOUT_MS = 90000; + const DEFAULT_CONVERSATION_RESOLVE_MS = 60000; const DEFAULT_FULL_READ_IDLE_WHEELS = 8; const DEFAULT_FULL_READ_MAX_WHEELS = 400; + const FULL_READ_WHEEL_DELTA_Y = -800; const COMPOSER_SELECTOR = `[${ATTR.composer}="true"][contenteditable="true"]`; const SEND_BUTTON_SELECTOR = 'button[aria-label="Send"]'; const STOP_BUTTON_SELECTOR = 'main button[aria-label="Stop"]'; @@ -12109,14 +12136,37 @@ var __webpack_modules__ = { return targets.find((t)=>isMainWindowTarget(t)) ?? null; } function dedupeThreadsById(threads) { - const seen = new Set(); - const out = []; + const byKey = new Map(); for (const thread of threads){ - if (!thread.threadId || seen.has(thread.threadId)) continue; - seen.add(thread.threadId); - out.push(thread); + if (!thread.threadId) continue; + const key = durableThreadKey(thread.threadId); + const existing = byKey.get(key); + if (!existing) { + byKey.set(key, thread); + continue; + } + byKey.set(key, preferThreadRow(existing, thread)); + } + return [ + ...byKey.values() + ]; + } + function durableThreadKey(threadId) { + if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + try { + return (0, _codex_thread_id_js__rspack_import_0.SX)(threadId); + } catch { + return threadId.startsWith("local:") ? threadId.slice("local:".length) || threadId : threadId; } - return out; + } + function toDesktopForm(threadId) { + if (!threadId || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + if (threadId.startsWith("local:")) return threadId; + return `${"local:"}${threadId}`; + } + function preferThreadRow(left, right) { + const score = (row)=>(row.selected ? 4 : 0) + (row.pinned ? 2 : 0) + (row.threadId.startsWith("local:") && !(0, _codex_thread_id_js__rspack_import_0.vr)(row.threadId) ? 1 : 0); + return score(right) > score(left) ? right : left; } const LIST_THREADS_EXPRESSION = `(() => { const skipProjectLabels = new Set(['Recent', 'Pinned', 'Threads', 'Chats']); @@ -12151,13 +12201,24 @@ var __webpack_modules__ = { return out; })()`; function openThreadExpression(threadId) { + const bare = durableThreadKey(threadId); + const desktop = toDesktopForm(bare); + const candidates = [ + ...new Set([ + threadId, + bare, + desktop + ].filter(Boolean)) + ]; return `(() => { - const id = ${JSON.stringify(threadId)}; + const candidates = ${JSON.stringify(candidates)}; const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); - const row = rows.find((el) => el.getAttribute(${JSON.stringify(ATTR.threadId)}) === id); + const row = rows.find((el) => + candidates.includes(el.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''), + ); if (!row) return { ok: false, error: 'thread-not-found' }; row.click(); - return { ok: true, threadId: id }; + return { ok: true, threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || candidates[0] }; })()`; } function startNewChatExpression(project) { @@ -12220,6 +12281,12 @@ var __webpack_modules__ = { reply, lastTurnKey, }; +})()`; + const CONVERSATION_ID_EXPRESSION = `(() => { + const annotation = document.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}); + return annotation + ? (annotation.getAttribute(${JSON.stringify(ATTR.conversationAnnotation)}) || '') + : ''; })()`; const HARVEST_VISIBLE_TURNS_EXPRESSION = `(() => { const gapPrefix = ${JSON.stringify(HISTORY_GAP_PREFIX)}; @@ -12401,6 +12468,32 @@ var __webpack_modules__ = { lastTurnKey: String(state?.lastTurnKey ?? '') }; } + async function readConversationIdFromDom(session, sessionId) { + const value = await session.evaluate(CONVERSATION_ID_EXPRESSION, { + sessionId + }); + return typeof value === 'string' ? value.trim() : ''; + } + async function waitForConversationId(session, sessionId, { timeoutMs = DEFAULT_CONVERSATION_RESOLVE_MS } = {}) { + const deadline = Date.now() + timeoutMs; + while(Date.now() < deadline){ + const id = await readConversationIdFromDom(session, sessionId); + if (id && !(0, _codex_thread_id_js__rspack_import_0.vr)(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { + return id; + } + await delay(200); + } + throw new Error(`ChatGPT Desktop conversation id did not appear on [data-response-annotation-conversation] within ${timeoutMs}ms`); + } + function resolveDurableThreadId(conversationId, fallbackThreadId) { + if (conversationId && !(0, _codex_thread_id_js__rspack_import_0.vr)(conversationId)) { + return toDesktopForm(conversationId); + } + if (fallbackThreadId && !(0, _codex_thread_id_js__rspack_import_0.vr)(fallbackThreadId) && fallbackThreadId !== 'new') { + return toDesktopForm(fallbackThreadId); + } + return null; + } async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0 } = {}) { const deadline = Date.now() + timeoutMs; let sawStop = false; @@ -12469,7 +12562,7 @@ var __webpack_modules__ = { x: metrics.x, y: metrics.y, deltaX: 0, - deltaY: -800 + deltaY: FULL_READ_WHEEL_DELTA_Y }, { sessionId }); @@ -12498,10 +12591,12 @@ var __webpack_modules__ = { JU: ()=>readTurnsFromDom, Kl: ()=>openThreadInDom, Mr: ()=>summarizeTargetInfos, + X8: ()=>resolveDurableThreadId, YX: ()=>readReplyState, Zx: ()=>waitForLoadingTaskGone, lh: ()=>sendMessageInDom, - s0: ()=>startNewChatInDom + s0: ()=>startNewChatInDom, + z9: ()=>waitForConversationId }, { hA: TEMP_THREAD_ID_PREFIX }); diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index 8a8440a..cdb1c54 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -10234,16 +10234,17 @@ var __webpack_modules__ = { var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _cdp_session_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); var _cdp_dom_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); - var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _loopback_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); class CdpChatGptDesktopAdapter { - #port = (0, _loopback_js__rspack_import_3.L0)(); + #port = (0, _loopback_js__rspack_import_4.L0)(); #session = null; #version = null; #pageSessionId = null; #mainTargetId = null; async connect({ port }) { await this.close(); - this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); const session = new _cdp_session_js__rspack_import_1.a(this.#port); try { this.#version = await session.connect(); @@ -10290,7 +10291,7 @@ var __webpack_modules__ = { async sendMessage({ threadId, text, project, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); let temporaryThreadId; - let resolvedThreadId = threadId ?? 'new'; + const startedNew = !threadId; if (threadId) { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } else { @@ -10302,15 +10303,24 @@ var __webpack_modules__ = { limit: 20 }); const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); - if (temp) { - temporaryThreadId = temp.threadId; - resolvedThreadId = temp.threadId; - } + if (temp) temporaryThreadId = temp.threadId; } const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + let conversationId; + if (startedNew || threadId && (0, _thread_ids_js__rspack_import_3.vr)(threadId)) { + const resolveMs = Math.min(openTimeoutMs, 60000); + conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { + timeoutMs: resolveMs + }); + } + const durable = (0, _cdp_dom_js__rspack_import_2.X8)(conversationId, threadId); + if (!durable) { + throw new Error('ChatGPT Desktop send accepted but no durable conversation id was available; ' + 'refusing to return a local:client-new-thread:* id as threadId'); + } return { - threadId: resolvedThreadId, + threadId: durable, temporaryThreadId, + conversationId: conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, project, backend: 'cdp', experimental: false, @@ -10321,7 +10331,7 @@ var __webpack_modules__ = { } async waitForReply({ threadId, timeoutMs = 120000 }) { const sessionId = await this.#ensurePageSession(); - if (threadId && !threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && threadId !== 'new') { + if (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) && threadId !== 'new') { try { await this.#openAndWait(sessionId, threadId, 90000); } catch {} @@ -10332,10 +10342,13 @@ var __webpack_modules__ = { timeoutMs, baselineFinalCount: baseline.finalAssistantCount }); - const resolvedId = done.conversationId || threadId || 'unknown'; + const durable = (0, _cdp_dom_js__rspack_import_2.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_3.BS)(done.conversationId) : null); + if (!durable) { + throw new Error('ChatGPT Desktop reply finished without a durable conversation id on ' + '[data-response-annotation-conversation]'); + } return { - threadId: resolvedId, - conversationId: done.conversationId || undefined, + threadId: durable, + conversationId: done.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, reply: done.reply, backend: 'cdp', experimental: false, @@ -10343,8 +10356,19 @@ var __webpack_modules__ = { }; } catch (error) { const last = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); + const durable = (0, _cdp_dom_js__rspack_import_2.X8)(last.conversationId, threadId); + if (last.reply && durable) { + return { + threadId: durable, + conversationId: last.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, + reply: last.reply, + backend: 'cdp', + experimental: false, + delivery: 'replied' + }; + } return { - threadId: last.conversationId || threadId || 'unknown', + threadId: durable ?? (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) ? threadId : 'unknown'), conversationId: last.conversationId || undefined, reply: last.reply, backend: 'cdp', @@ -10446,6 +10470,7 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_thread_id_js__rspack_import_0 = __webpack_require__("./src/core/codex/thread-id.js"); const MAIN_WINDOW_URL = 'app://-/index.html'; const IGNORED_TARGET_URL_MARKERS = [ 'initialRoute=%2Favatar-overlay', @@ -10474,8 +10499,10 @@ var __webpack_modules__ = { const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; const LOADING_TASK_TEXT = 'Loading task…'; const DEFAULT_OPEN_TIMEOUT_MS = 90000; + const DEFAULT_CONVERSATION_RESOLVE_MS = 60000; const DEFAULT_FULL_READ_IDLE_WHEELS = 8; const DEFAULT_FULL_READ_MAX_WHEELS = 400; + const FULL_READ_WHEEL_DELTA_Y = -800; const COMPOSER_SELECTOR = `[${ATTR.composer}="true"][contenteditable="true"]`; const SEND_BUTTON_SELECTOR = 'button[aria-label="Send"]'; const STOP_BUTTON_SELECTOR = 'main button[aria-label="Stop"]'; @@ -10517,14 +10544,37 @@ var __webpack_modules__ = { return targets.find((t)=>isMainWindowTarget(t)) ?? null; } function dedupeThreadsById(threads) { - const seen = new Set(); - const out = []; + const byKey = new Map(); for (const thread of threads){ - if (!thread.threadId || seen.has(thread.threadId)) continue; - seen.add(thread.threadId); - out.push(thread); + if (!thread.threadId) continue; + const key = durableThreadKey(thread.threadId); + const existing = byKey.get(key); + if (!existing) { + byKey.set(key, thread); + continue; + } + byKey.set(key, preferThreadRow(existing, thread)); + } + return [ + ...byKey.values() + ]; + } + function durableThreadKey(threadId) { + if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + try { + return (0, _codex_thread_id_js__rspack_import_0.SX)(threadId); + } catch { + return threadId.startsWith("local:") ? threadId.slice("local:".length) || threadId : threadId; } - return out; + } + function toDesktopForm(threadId) { + if (!threadId || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + if (threadId.startsWith("local:")) return threadId; + return `${"local:"}${threadId}`; + } + function preferThreadRow(left, right) { + const score = (row)=>(row.selected ? 4 : 0) + (row.pinned ? 2 : 0) + (row.threadId.startsWith("local:") && !(0, _codex_thread_id_js__rspack_import_0.vr)(row.threadId) ? 1 : 0); + return score(right) > score(left) ? right : left; } const LIST_THREADS_EXPRESSION = `(() => { const skipProjectLabels = new Set(['Recent', 'Pinned', 'Threads', 'Chats']); @@ -10559,13 +10609,24 @@ var __webpack_modules__ = { return out; })()`; function openThreadExpression(threadId) { + const bare = durableThreadKey(threadId); + const desktop = toDesktopForm(bare); + const candidates = [ + ...new Set([ + threadId, + bare, + desktop + ].filter(Boolean)) + ]; return `(() => { - const id = ${JSON.stringify(threadId)}; + const candidates = ${JSON.stringify(candidates)}; const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); - const row = rows.find((el) => el.getAttribute(${JSON.stringify(ATTR.threadId)}) === id); + const row = rows.find((el) => + candidates.includes(el.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''), + ); if (!row) return { ok: false, error: 'thread-not-found' }; row.click(); - return { ok: true, threadId: id }; + return { ok: true, threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || candidates[0] }; })()`; } function startNewChatExpression(project) { @@ -10628,6 +10689,12 @@ var __webpack_modules__ = { reply, lastTurnKey, }; +})()`; + const CONVERSATION_ID_EXPRESSION = `(() => { + const annotation = document.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}); + return annotation + ? (annotation.getAttribute(${JSON.stringify(ATTR.conversationAnnotation)}) || '') + : ''; })()`; const HARVEST_VISIBLE_TURNS_EXPRESSION = `(() => { const gapPrefix = ${JSON.stringify(HISTORY_GAP_PREFIX)}; @@ -10809,6 +10876,32 @@ var __webpack_modules__ = { lastTurnKey: String(state?.lastTurnKey ?? '') }; } + async function readConversationIdFromDom(session, sessionId) { + const value = await session.evaluate(CONVERSATION_ID_EXPRESSION, { + sessionId + }); + return typeof value === 'string' ? value.trim() : ''; + } + async function waitForConversationId(session, sessionId, { timeoutMs = DEFAULT_CONVERSATION_RESOLVE_MS } = {}) { + const deadline = Date.now() + timeoutMs; + while(Date.now() < deadline){ + const id = await readConversationIdFromDom(session, sessionId); + if (id && !(0, _codex_thread_id_js__rspack_import_0.vr)(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { + return id; + } + await delay(200); + } + throw new Error(`ChatGPT Desktop conversation id did not appear on [data-response-annotation-conversation] within ${timeoutMs}ms`); + } + function resolveDurableThreadId(conversationId, fallbackThreadId) { + if (conversationId && !(0, _codex_thread_id_js__rspack_import_0.vr)(conversationId)) { + return toDesktopForm(conversationId); + } + if (fallbackThreadId && !(0, _codex_thread_id_js__rspack_import_0.vr)(fallbackThreadId) && fallbackThreadId !== 'new') { + return toDesktopForm(fallbackThreadId); + } + return null; + } async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0 } = {}) { const deadline = Date.now() + timeoutMs; let sawStop = false; @@ -10877,7 +10970,7 @@ var __webpack_modules__ = { x: metrics.x, y: metrics.y, deltaX: 0, - deltaY: -800 + deltaY: FULL_READ_WHEEL_DELTA_Y }, { sessionId }); @@ -10906,10 +10999,12 @@ var __webpack_modules__ = { JU: ()=>readTurnsFromDom, Kl: ()=>openThreadInDom, Mr: ()=>summarizeTargetInfos, + X8: ()=>resolveDurableThreadId, YX: ()=>readReplyState, Zx: ()=>waitForLoadingTaskGone, lh: ()=>sendMessageInDom, - s0: ()=>startNewChatInDom + s0: ()=>startNewChatInDom, + z9: ()=>waitForConversationId }, { hA: TEMP_THREAD_ID_PREFIX }); diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index e3dcf99..c210fb8 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8641,16 +8641,17 @@ var __webpack_modules__ = { var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _cdp_session_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); var _cdp_dom_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); - var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _loopback_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); class CdpChatGptDesktopAdapter { - #port = (0, _loopback_js__rspack_import_3.L0)(); + #port = (0, _loopback_js__rspack_import_4.L0)(); #session = null; #version = null; #pageSessionId = null; #mainTargetId = null; async connect({ port }) { await this.close(); - this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); const session = new _cdp_session_js__rspack_import_1.a(this.#port); try { this.#version = await session.connect(); @@ -8697,7 +8698,7 @@ var __webpack_modules__ = { async sendMessage({ threadId, text, project, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); let temporaryThreadId; - let resolvedThreadId = threadId ?? 'new'; + const startedNew = !threadId; if (threadId) { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } else { @@ -8709,15 +8710,24 @@ var __webpack_modules__ = { limit: 20 }); const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); - if (temp) { - temporaryThreadId = temp.threadId; - resolvedThreadId = temp.threadId; - } + if (temp) temporaryThreadId = temp.threadId; } const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + let conversationId; + if (startedNew || threadId && (0, _thread_ids_js__rspack_import_3.vr)(threadId)) { + const resolveMs = Math.min(openTimeoutMs, 60000); + conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { + timeoutMs: resolveMs + }); + } + const durable = (0, _cdp_dom_js__rspack_import_2.X8)(conversationId, threadId); + if (!durable) { + throw new Error('ChatGPT Desktop send accepted but no durable conversation id was available; ' + 'refusing to return a local:client-new-thread:* id as threadId'); + } return { - threadId: resolvedThreadId, + threadId: durable, temporaryThreadId, + conversationId: conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, project, backend: 'cdp', experimental: false, @@ -8728,7 +8738,7 @@ var __webpack_modules__ = { } async waitForReply({ threadId, timeoutMs = 120000 }) { const sessionId = await this.#ensurePageSession(); - if (threadId && !threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && threadId !== 'new') { + if (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) && threadId !== 'new') { try { await this.#openAndWait(sessionId, threadId, 90000); } catch {} @@ -8739,10 +8749,13 @@ var __webpack_modules__ = { timeoutMs, baselineFinalCount: baseline.finalAssistantCount }); - const resolvedId = done.conversationId || threadId || 'unknown'; + const durable = (0, _cdp_dom_js__rspack_import_2.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_3.BS)(done.conversationId) : null); + if (!durable) { + throw new Error('ChatGPT Desktop reply finished without a durable conversation id on ' + '[data-response-annotation-conversation]'); + } return { - threadId: resolvedId, - conversationId: done.conversationId || undefined, + threadId: durable, + conversationId: done.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, reply: done.reply, backend: 'cdp', experimental: false, @@ -8750,8 +8763,19 @@ var __webpack_modules__ = { }; } catch (error) { const last = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); + const durable = (0, _cdp_dom_js__rspack_import_2.X8)(last.conversationId, threadId); + if (last.reply && durable) { + return { + threadId: durable, + conversationId: last.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, + reply: last.reply, + backend: 'cdp', + experimental: false, + delivery: 'replied' + }; + } return { - threadId: last.conversationId || threadId || 'unknown', + threadId: durable ?? (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) ? threadId : 'unknown'), conversationId: last.conversationId || undefined, reply: last.reply, backend: 'cdp', @@ -8853,6 +8877,7 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_thread_id_js__rspack_import_0 = __webpack_require__("./src/core/codex/thread-id.js"); const MAIN_WINDOW_URL = 'app://-/index.html'; const IGNORED_TARGET_URL_MARKERS = [ 'initialRoute=%2Favatar-overlay', @@ -8881,8 +8906,10 @@ var __webpack_modules__ = { const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; const LOADING_TASK_TEXT = 'Loading task…'; const DEFAULT_OPEN_TIMEOUT_MS = 90000; + const DEFAULT_CONVERSATION_RESOLVE_MS = 60000; const DEFAULT_FULL_READ_IDLE_WHEELS = 8; const DEFAULT_FULL_READ_MAX_WHEELS = 400; + const FULL_READ_WHEEL_DELTA_Y = -800; const COMPOSER_SELECTOR = `[${ATTR.composer}="true"][contenteditable="true"]`; const SEND_BUTTON_SELECTOR = 'button[aria-label="Send"]'; const STOP_BUTTON_SELECTOR = 'main button[aria-label="Stop"]'; @@ -8924,14 +8951,37 @@ var __webpack_modules__ = { return targets.find((t)=>isMainWindowTarget(t)) ?? null; } function dedupeThreadsById(threads) { - const seen = new Set(); - const out = []; + const byKey = new Map(); for (const thread of threads){ - if (!thread.threadId || seen.has(thread.threadId)) continue; - seen.add(thread.threadId); - out.push(thread); + if (!thread.threadId) continue; + const key = durableThreadKey(thread.threadId); + const existing = byKey.get(key); + if (!existing) { + byKey.set(key, thread); + continue; + } + byKey.set(key, preferThreadRow(existing, thread)); + } + return [ + ...byKey.values() + ]; + } + function durableThreadKey(threadId) { + if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + try { + return (0, _codex_thread_id_js__rspack_import_0.SX)(threadId); + } catch { + return threadId.startsWith("local:") ? threadId.slice("local:".length) || threadId : threadId; } - return out; + } + function toDesktopForm(threadId) { + if (!threadId || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + if (threadId.startsWith("local:")) return threadId; + return `${"local:"}${threadId}`; + } + function preferThreadRow(left, right) { + const score = (row)=>(row.selected ? 4 : 0) + (row.pinned ? 2 : 0) + (row.threadId.startsWith("local:") && !(0, _codex_thread_id_js__rspack_import_0.vr)(row.threadId) ? 1 : 0); + return score(right) > score(left) ? right : left; } const LIST_THREADS_EXPRESSION = `(() => { const skipProjectLabels = new Set(['Recent', 'Pinned', 'Threads', 'Chats']); @@ -8966,13 +9016,24 @@ var __webpack_modules__ = { return out; })()`; function openThreadExpression(threadId) { + const bare = durableThreadKey(threadId); + const desktop = toDesktopForm(bare); + const candidates = [ + ...new Set([ + threadId, + bare, + desktop + ].filter(Boolean)) + ]; return `(() => { - const id = ${JSON.stringify(threadId)}; + const candidates = ${JSON.stringify(candidates)}; const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); - const row = rows.find((el) => el.getAttribute(${JSON.stringify(ATTR.threadId)}) === id); + const row = rows.find((el) => + candidates.includes(el.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''), + ); if (!row) return { ok: false, error: 'thread-not-found' }; row.click(); - return { ok: true, threadId: id }; + return { ok: true, threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || candidates[0] }; })()`; } function startNewChatExpression(project) { @@ -9035,6 +9096,12 @@ var __webpack_modules__ = { reply, lastTurnKey, }; +})()`; + const CONVERSATION_ID_EXPRESSION = `(() => { + const annotation = document.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}); + return annotation + ? (annotation.getAttribute(${JSON.stringify(ATTR.conversationAnnotation)}) || '') + : ''; })()`; const HARVEST_VISIBLE_TURNS_EXPRESSION = `(() => { const gapPrefix = ${JSON.stringify(HISTORY_GAP_PREFIX)}; @@ -9216,6 +9283,32 @@ var __webpack_modules__ = { lastTurnKey: String(state?.lastTurnKey ?? '') }; } + async function readConversationIdFromDom(session, sessionId) { + const value = await session.evaluate(CONVERSATION_ID_EXPRESSION, { + sessionId + }); + return typeof value === 'string' ? value.trim() : ''; + } + async function waitForConversationId(session, sessionId, { timeoutMs = DEFAULT_CONVERSATION_RESOLVE_MS } = {}) { + const deadline = Date.now() + timeoutMs; + while(Date.now() < deadline){ + const id = await readConversationIdFromDom(session, sessionId); + if (id && !(0, _codex_thread_id_js__rspack_import_0.vr)(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { + return id; + } + await delay(200); + } + throw new Error(`ChatGPT Desktop conversation id did not appear on [data-response-annotation-conversation] within ${timeoutMs}ms`); + } + function resolveDurableThreadId(conversationId, fallbackThreadId) { + if (conversationId && !(0, _codex_thread_id_js__rspack_import_0.vr)(conversationId)) { + return toDesktopForm(conversationId); + } + if (fallbackThreadId && !(0, _codex_thread_id_js__rspack_import_0.vr)(fallbackThreadId) && fallbackThreadId !== 'new') { + return toDesktopForm(fallbackThreadId); + } + return null; + } async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0 } = {}) { const deadline = Date.now() + timeoutMs; let sawStop = false; @@ -9284,7 +9377,7 @@ var __webpack_modules__ = { x: metrics.x, y: metrics.y, deltaX: 0, - deltaY: -800 + deltaY: FULL_READ_WHEEL_DELTA_Y }, { sessionId }); @@ -9313,10 +9406,12 @@ var __webpack_modules__ = { JU: ()=>readTurnsFromDom, Kl: ()=>openThreadInDom, Mr: ()=>summarizeTargetInfos, + X8: ()=>resolveDurableThreadId, YX: ()=>readReplyState, Zx: ()=>waitForLoadingTaskGone, lh: ()=>sendMessageInDom, - s0: ()=>startNewChatInDom + s0: ()=>startNewChatInDom, + z9: ()=>waitForConversationId }, { hA: TEMP_THREAD_ID_PREFIX }); @@ -11637,7 +11732,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop send', - description: 'Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.', + description: 'Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.', annotations: { readOnlyHint: false }, @@ -27980,7 +28075,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": false }, - "description": "Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.", + "description": "Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.", "inputJsonSchema": { "additionalProperties": false, "properties": { diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index 561d9f1..e816dd7 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -7049,16 +7049,17 @@ var __webpack_modules__ = { var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _cdp_session_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); var _cdp_dom_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); - var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _loopback_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); class CdpChatGptDesktopAdapter { - #port = (0, _loopback_js__rspack_import_3.L0)(); + #port = (0, _loopback_js__rspack_import_4.L0)(); #session = null; #version = null; #pageSessionId = null; #mainTargetId = null; async connect({ port }) { await this.close(); - this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); const session = new _cdp_session_js__rspack_import_1.a(this.#port); try { this.#version = await session.connect(); @@ -7105,7 +7106,7 @@ var __webpack_modules__ = { async sendMessage({ threadId, text, project, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); let temporaryThreadId; - let resolvedThreadId = threadId ?? 'new'; + const startedNew = !threadId; if (threadId) { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } else { @@ -7117,15 +7118,24 @@ var __webpack_modules__ = { limit: 20 }); const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); - if (temp) { - temporaryThreadId = temp.threadId; - resolvedThreadId = temp.threadId; - } + if (temp) temporaryThreadId = temp.threadId; } const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + let conversationId; + if (startedNew || threadId && (0, _thread_ids_js__rspack_import_3.vr)(threadId)) { + const resolveMs = Math.min(openTimeoutMs, 60000); + conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { + timeoutMs: resolveMs + }); + } + const durable = (0, _cdp_dom_js__rspack_import_2.X8)(conversationId, threadId); + if (!durable) { + throw new Error('ChatGPT Desktop send accepted but no durable conversation id was available; ' + 'refusing to return a local:client-new-thread:* id as threadId'); + } return { - threadId: resolvedThreadId, + threadId: durable, temporaryThreadId, + conversationId: conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, project, backend: 'cdp', experimental: false, @@ -7136,7 +7146,7 @@ var __webpack_modules__ = { } async waitForReply({ threadId, timeoutMs = 120000 }) { const sessionId = await this.#ensurePageSession(); - if (threadId && !threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && threadId !== 'new') { + if (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) && threadId !== 'new') { try { await this.#openAndWait(sessionId, threadId, 90000); } catch {} @@ -7147,10 +7157,13 @@ var __webpack_modules__ = { timeoutMs, baselineFinalCount: baseline.finalAssistantCount }); - const resolvedId = done.conversationId || threadId || 'unknown'; + const durable = (0, _cdp_dom_js__rspack_import_2.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_3.BS)(done.conversationId) : null); + if (!durable) { + throw new Error('ChatGPT Desktop reply finished without a durable conversation id on ' + '[data-response-annotation-conversation]'); + } return { - threadId: resolvedId, - conversationId: done.conversationId || undefined, + threadId: durable, + conversationId: done.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, reply: done.reply, backend: 'cdp', experimental: false, @@ -7158,8 +7171,19 @@ var __webpack_modules__ = { }; } catch (error) { const last = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); + const durable = (0, _cdp_dom_js__rspack_import_2.X8)(last.conversationId, threadId); + if (last.reply && durable) { + return { + threadId: durable, + conversationId: last.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, + reply: last.reply, + backend: 'cdp', + experimental: false, + delivery: 'replied' + }; + } return { - threadId: last.conversationId || threadId || 'unknown', + threadId: durable ?? (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) ? threadId : 'unknown'), conversationId: last.conversationId || undefined, reply: last.reply, backend: 'cdp', @@ -7261,6 +7285,7 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_thread_id_js__rspack_import_0 = __webpack_require__("./src/core/codex/thread-id.js"); const MAIN_WINDOW_URL = 'app://-/index.html'; const IGNORED_TARGET_URL_MARKERS = [ 'initialRoute=%2Favatar-overlay', @@ -7289,8 +7314,10 @@ var __webpack_modules__ = { const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; const LOADING_TASK_TEXT = 'Loading task…'; const DEFAULT_OPEN_TIMEOUT_MS = 90000; + const DEFAULT_CONVERSATION_RESOLVE_MS = 60000; const DEFAULT_FULL_READ_IDLE_WHEELS = 8; const DEFAULT_FULL_READ_MAX_WHEELS = 400; + const FULL_READ_WHEEL_DELTA_Y = -800; const COMPOSER_SELECTOR = `[${ATTR.composer}="true"][contenteditable="true"]`; const SEND_BUTTON_SELECTOR = 'button[aria-label="Send"]'; const STOP_BUTTON_SELECTOR = 'main button[aria-label="Stop"]'; @@ -7332,14 +7359,37 @@ var __webpack_modules__ = { return targets.find((t)=>isMainWindowTarget(t)) ?? null; } function dedupeThreadsById(threads) { - const seen = new Set(); - const out = []; + const byKey = new Map(); for (const thread of threads){ - if (!thread.threadId || seen.has(thread.threadId)) continue; - seen.add(thread.threadId); - out.push(thread); + if (!thread.threadId) continue; + const key = durableThreadKey(thread.threadId); + const existing = byKey.get(key); + if (!existing) { + byKey.set(key, thread); + continue; + } + byKey.set(key, preferThreadRow(existing, thread)); + } + return [ + ...byKey.values() + ]; + } + function durableThreadKey(threadId) { + if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + try { + return (0, _codex_thread_id_js__rspack_import_0.SX)(threadId); + } catch { + return threadId.startsWith("local:") ? threadId.slice("local:".length) || threadId : threadId; } - return out; + } + function toDesktopForm(threadId) { + if (!threadId || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + if (threadId.startsWith("local:")) return threadId; + return `${"local:"}${threadId}`; + } + function preferThreadRow(left, right) { + const score = (row)=>(row.selected ? 4 : 0) + (row.pinned ? 2 : 0) + (row.threadId.startsWith("local:") && !(0, _codex_thread_id_js__rspack_import_0.vr)(row.threadId) ? 1 : 0); + return score(right) > score(left) ? right : left; } const LIST_THREADS_EXPRESSION = `(() => { const skipProjectLabels = new Set(['Recent', 'Pinned', 'Threads', 'Chats']); @@ -7374,13 +7424,24 @@ var __webpack_modules__ = { return out; })()`; function openThreadExpression(threadId) { + const bare = durableThreadKey(threadId); + const desktop = toDesktopForm(bare); + const candidates = [ + ...new Set([ + threadId, + bare, + desktop + ].filter(Boolean)) + ]; return `(() => { - const id = ${JSON.stringify(threadId)}; + const candidates = ${JSON.stringify(candidates)}; const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); - const row = rows.find((el) => el.getAttribute(${JSON.stringify(ATTR.threadId)}) === id); + const row = rows.find((el) => + candidates.includes(el.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''), + ); if (!row) return { ok: false, error: 'thread-not-found' }; row.click(); - return { ok: true, threadId: id }; + return { ok: true, threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || candidates[0] }; })()`; } function startNewChatExpression(project) { @@ -7443,6 +7504,12 @@ var __webpack_modules__ = { reply, lastTurnKey, }; +})()`; + const CONVERSATION_ID_EXPRESSION = `(() => { + const annotation = document.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}); + return annotation + ? (annotation.getAttribute(${JSON.stringify(ATTR.conversationAnnotation)}) || '') + : ''; })()`; const HARVEST_VISIBLE_TURNS_EXPRESSION = `(() => { const gapPrefix = ${JSON.stringify(HISTORY_GAP_PREFIX)}; @@ -7624,6 +7691,32 @@ var __webpack_modules__ = { lastTurnKey: String(state?.lastTurnKey ?? '') }; } + async function readConversationIdFromDom(session, sessionId) { + const value = await session.evaluate(CONVERSATION_ID_EXPRESSION, { + sessionId + }); + return typeof value === 'string' ? value.trim() : ''; + } + async function waitForConversationId(session, sessionId, { timeoutMs = DEFAULT_CONVERSATION_RESOLVE_MS } = {}) { + const deadline = Date.now() + timeoutMs; + while(Date.now() < deadline){ + const id = await readConversationIdFromDom(session, sessionId); + if (id && !(0, _codex_thread_id_js__rspack_import_0.vr)(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { + return id; + } + await delay(200); + } + throw new Error(`ChatGPT Desktop conversation id did not appear on [data-response-annotation-conversation] within ${timeoutMs}ms`); + } + function resolveDurableThreadId(conversationId, fallbackThreadId) { + if (conversationId && !(0, _codex_thread_id_js__rspack_import_0.vr)(conversationId)) { + return toDesktopForm(conversationId); + } + if (fallbackThreadId && !(0, _codex_thread_id_js__rspack_import_0.vr)(fallbackThreadId) && fallbackThreadId !== 'new') { + return toDesktopForm(fallbackThreadId); + } + return null; + } async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0 } = {}) { const deadline = Date.now() + timeoutMs; let sawStop = false; @@ -7692,7 +7785,7 @@ var __webpack_modules__ = { x: metrics.x, y: metrics.y, deltaX: 0, - deltaY: -800 + deltaY: FULL_READ_WHEEL_DELTA_Y }, { sessionId }); @@ -7721,10 +7814,12 @@ var __webpack_modules__ = { JU: ()=>readTurnsFromDom, Kl: ()=>openThreadInDom, Mr: ()=>summarizeTargetInfos, + X8: ()=>resolveDurableThreadId, YX: ()=>readReplyState, Zx: ()=>waitForLoadingTaskGone, lh: ()=>sendMessageInDom, - s0: ()=>startNewChatInDom + s0: ()=>startNewChatInDom, + z9: ()=>waitForConversationId }, { hA: TEMP_THREAD_ID_PREFIX }); @@ -10045,7 +10140,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop send', - description: 'Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.', + description: 'Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.', annotations: { readOnlyHint: false }, @@ -59488,7 +59583,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": false }, - "description": "Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.", + "description": "Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.", "inputJsonSchema": { "additionalProperties": false, "properties": { diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index 1786e75..ca12191 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -157,9 +157,11 @@ All selectors live in `src/core/chatgpt-desktop/cdp-dom.ts`: - Reply done: `main button[aria-label="Stop"]` gone + new `[data-local-conversation-final-assistant=true]` - Reply text: last turn’s `[data-local-conversation-final-assistant=true] [data-markdown-text-style=assistant-message]` - New chat: `button[aria-label="Start new chat in "]` (preferred) or sidebar “New chat” -- Conversation id: `[data-response-annotation-conversation]` (resolves `local:client-new-thread:…`) -- Open / selected: click sidebar row, wait until “Loading task…” clears (default 90s) -- Read fallback: harvest rendered turns; optional mouseWheel on `[data-app-action-timeline-scroll]` +- Conversation id: `[data-response-annotation-conversation]` — after a new-thread send, `threadId` is this durable id (never `local:client-new-thread:…`; that may appear only as `temporaryThreadId`) +- Open / selected: click sidebar row (bare or `local:` id), wait until “Loading task…” clears (default 90s, timed out) +- Read fallback: harvest rendered turns; full history uses mouseWheel (`deltaY` negative) because the timeline is column-reverse (`scrollTop` 0 is newest and does not load older turns) +- Target attach: exact `app://-/index.html` via `Target.getTargets` (not `/json/list` order) +- CDP: 127.0.0.1 only ## App-server reuse diff --git a/src/core/chatgpt-desktop/cdp-adapter.ts b/src/core/chatgpt-desktop/cdp-adapter.ts index 8fe6488..749fa09 100644 --- a/src/core/chatgpt-desktop/cdp-adapter.ts +++ b/src/core/chatgpt-desktop/cdp-adapter.ts @@ -2,6 +2,7 @@ import type { ChatGptDesktopAdapter } from './adapter.js'; import { CdpUnreachableError } from './errors.js'; import { CdpSession } from './cdp-session.js'; import { + DEFAULT_CONVERSATION_RESOLVE_MS, DEFAULT_OPEN_TIMEOUT_MS, TEMP_THREAD_ID_PREFIX, listThreadsFromDom, @@ -9,12 +10,15 @@ import { pickMainWindowTarget, readReplyState, readTurnsFromDom, + resolveDurableThreadId, sendMessageInDom, startNewChatInDom, summarizeTargetInfos, + waitForConversationId, waitForLoadingTaskGone, waitForReplyDone, } from './cdp-dom.js'; +import { isTemporaryDesktopThreadId, toAppServerThreadId, toDesktopThreadId } from './thread-ids.js'; import { resolveCdpPort } from './loopback.js'; import type { ChatGptDesktopStatus, @@ -108,7 +112,7 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { }): Promise { const sessionId = await this.#ensurePageSession(); let temporaryThreadId: string | undefined; - let resolvedThreadId = threadId ?? 'new'; + const startedNew = !threadId; if (threadId) { await this.#openAndWait(sessionId, threadId, openTimeoutMs); @@ -118,16 +122,31 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { const threads = await listThreadsFromDom(this.#requireSession(), sessionId, { limit: 20 }); const temp = threads.find((t) => t.threadId.startsWith(TEMP_THREAD_ID_PREFIX) && t.selected) ?? threads.find((t) => t.threadId.startsWith(TEMP_THREAD_ID_PREFIX)); - if (temp) { - temporaryThreadId = temp.threadId; - resolvedThreadId = temp.threadId; - } + if (temp) temporaryThreadId = temp.threadId; } const { sentVia } = await sendMessageInDom(this.#requireSession(), sessionId, text); + + let conversationId: string | undefined; + if (startedNew || (threadId && isTemporaryDesktopThreadId(threadId))) { + const resolveMs = Math.min(openTimeoutMs, DEFAULT_CONVERSATION_RESOLVE_MS); + conversationId = await waitForConversationId(this.#requireSession(), sessionId, { + timeoutMs: resolveMs, + }); + } + + const durable = resolveDurableThreadId(conversationId, threadId); + if (!durable) { + throw new Error( + 'ChatGPT Desktop send accepted but no durable conversation id was available; ' + + 'refusing to return a local:client-new-thread:* id as threadId', + ); + } + return { - threadId: resolvedThreadId, + threadId: durable, temporaryThreadId, + conversationId: conversationId || toAppServerThreadId(durable) || durable, project, backend: 'cdp', experimental: false, @@ -145,7 +164,7 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { timeoutMs?: number; }): Promise { const sessionId = await this.#ensurePageSession(); - if (threadId && !threadId.startsWith(TEMP_THREAD_ID_PREFIX) && threadId !== 'new') { + if (threadId && !isTemporaryDesktopThreadId(threadId) && threadId !== 'new') { // Stay on the current chat for temp/new; otherwise ensure the thread is open. try { await this.#openAndWait(sessionId, threadId, DEFAULT_OPEN_TIMEOUT_MS); @@ -160,10 +179,18 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { timeoutMs, baselineFinalCount: baseline.finalAssistantCount, }); - const resolvedId = done.conversationId || threadId || 'unknown'; + const durable = + resolveDurableThreadId(done.conversationId, threadId) + ?? (done.conversationId ? toDesktopThreadId(done.conversationId) : null); + if (!durable) { + throw new Error( + 'ChatGPT Desktop reply finished without a durable conversation id on ' + + '[data-response-annotation-conversation]', + ); + } return { - threadId: resolvedId, - conversationId: done.conversationId || undefined, + threadId: durable, + conversationId: done.conversationId || toAppServerThreadId(durable) || durable, reply: done.reply, backend: 'cdp', experimental: false, @@ -171,8 +198,19 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { }; } catch (error) { const last = await readReplyState(this.#requireSession(), sessionId); + const durable = resolveDurableThreadId(last.conversationId, threadId); + if (last.reply && durable) { + return { + threadId: durable, + conversationId: last.conversationId || toAppServerThreadId(durable) || durable, + reply: last.reply, + backend: 'cdp', + experimental: false, + delivery: 'replied', + }; + } return { - threadId: last.conversationId || threadId || 'unknown', + threadId: durable ?? (threadId && !isTemporaryDesktopThreadId(threadId) ? threadId : 'unknown'), conversationId: last.conversationId || undefined, reply: last.reply, backend: 'cdp', diff --git a/src/core/chatgpt-desktop/cdp-dom.ts b/src/core/chatgpt-desktop/cdp-dom.ts index 5781410..aa32bfc 100644 --- a/src/core/chatgpt-desktop/cdp-dom.ts +++ b/src/core/chatgpt-desktop/cdp-dom.ts @@ -7,6 +7,11 @@ import type { ChatGptDesktopTarget, ChatGptDesktopThread, ChatGptDesktopTurn } from './types.js'; import type { CdpSession } from './cdp-session.js'; +import { + LOCAL_THREAD_ID_PREFIX, + isTemporaryDesktopThreadId, + normalizeCodexThreadId, +} from '../codex/thread-id.js'; /** Exact main-window URL; ignore overlays / detached / webviews. */ export const MAIN_WINDOW_URL = 'app://-/index.html'; @@ -40,8 +45,16 @@ export const HISTORY_GAP_PREFIX = 'history-gap:'; export const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; export const LOADING_TASK_TEXT = 'Loading task…'; export const DEFAULT_OPEN_TIMEOUT_MS = 90_000; +/** How long a new-thread send waits for the real conversation annotation. */ +export const DEFAULT_CONVERSATION_RESOLVE_MS = 60_000; export const DEFAULT_FULL_READ_IDLE_WHEELS = 8; export const DEFAULT_FULL_READ_MAX_WHEELS = 400; +/** + * Timeline is `column-reverse`: scrollTop 0 is the newest message. Setting + * scrollTop does not load older history — use mouseWheel with this deltaY + * (negative = toward older turns). + */ +export const FULL_READ_WHEEL_DELTA_Y = -800; /** Verified composer: contenteditable textbox. */ export const COMPOSER_SELECTOR = @@ -121,14 +134,48 @@ export function pickMainWindowTarget( export function dedupeThreadsById( threads: readonly ChatGptDesktopThread[], ): ChatGptDesktopThread[] { - const seen = new Set(); - const out: ChatGptDesktopThread[] = []; + const byKey = new Map(); for (const thread of threads) { - if (!thread.threadId || seen.has(thread.threadId)) continue; - seen.add(thread.threadId); - out.push(thread); + if (!thread.threadId) continue; + const key = durableThreadKey(thread.threadId); + const existing = byKey.get(key); + if (!existing) { + byKey.set(key, thread); + continue; + } + byKey.set(key, preferThreadRow(existing, thread)); } - return out; + return [...byKey.values()]; +} + +function durableThreadKey(threadId: string): string { + if (isTemporaryDesktopThreadId(threadId)) return threadId; + try { + return normalizeCodexThreadId(threadId); + } catch { + return threadId.startsWith(LOCAL_THREAD_ID_PREFIX) + ? threadId.slice(LOCAL_THREAD_ID_PREFIX.length) || threadId + : threadId; + } +} + +function toDesktopForm(threadId: string): string { + if (!threadId || isTemporaryDesktopThreadId(threadId)) return threadId; + if (threadId.startsWith(LOCAL_THREAD_ID_PREFIX)) return threadId; + return `${LOCAL_THREAD_ID_PREFIX}${threadId}`; +} + +function preferThreadRow( + left: ChatGptDesktopThread, + right: ChatGptDesktopThread, +): ChatGptDesktopThread { + const score = (row: ChatGptDesktopThread) => + (row.selected ? 4 : 0) + + (row.pinned ? 2 : 0) + + (row.threadId.startsWith(LOCAL_THREAD_ID_PREFIX) && !isTemporaryDesktopThreadId(row.threadId) + ? 1 + : 0); + return score(right) > score(left) ? right : left; } export const LIST_THREADS_EXPRESSION = `(() => { @@ -165,13 +212,18 @@ export const LIST_THREADS_EXPRESSION = `(() => { })()`; export function openThreadExpression(threadId: string): string { + const bare = durableThreadKey(threadId); + const desktop = toDesktopForm(bare); + const candidates = [...new Set([threadId, bare, desktop].filter(Boolean))]; return `(() => { - const id = ${JSON.stringify(threadId)}; + const candidates = ${JSON.stringify(candidates)}; const rows = Array.from(document.querySelectorAll(${JSON.stringify(SELECTORS.threadRow)})); - const row = rows.find((el) => el.getAttribute(${JSON.stringify(ATTR.threadId)}) === id); + const row = rows.find((el) => + candidates.includes(el.getAttribute(${JSON.stringify(ATTR.threadId)}) || ''), + ); if (!row) return { ok: false, error: 'thread-not-found' }; row.click(); - return { ok: true, threadId: id }; + return { ok: true, threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || candidates[0] }; })()`; } @@ -240,6 +292,14 @@ export const REPLY_STATE_EXPRESSION = `(() => { }; })()`; +/** Any conversation annotation on the page (user turn or assistant). */ +export const CONVERSATION_ID_EXPRESSION = `(() => { + const annotation = document.querySelector(${JSON.stringify(CONVERSATION_ANNOTATION_SELECTOR)}); + return annotation + ? (annotation.getAttribute(${JSON.stringify(ATTR.conversationAnnotation)}) || '') + : ''; +})()`; + /** * Harvest currently rendered turns (no wheel). One turn may hold both the user * bubble and the final assistant reply. Skip history-gap placeholders. @@ -460,6 +520,57 @@ export async function readReplyState( }; } +/** Read the current `data-response-annotation-conversation` value, if any. */ +export async function readConversationIdFromDom( + session: CdpSession, + sessionId: string, +): Promise { + const value = await session.evaluate(CONVERSATION_ID_EXPRESSION, { sessionId }); + return typeof value === 'string' ? value.trim() : ''; +} + +/** + * Wait until the real conversation id appears on + * `[data-response-annotation-conversation]`. Rejects temporary sidebar ids. + */ +export async function waitForConversationId( + session: CdpSession, + sessionId: string, + { timeoutMs = DEFAULT_CONVERSATION_RESOLVE_MS }: { timeoutMs?: number } = {}, +): Promise { + const deadline = Date.now() + timeoutMs; + while (Date.now() < deadline) { + const id = await readConversationIdFromDom(session, sessionId); + if (id && !isTemporaryDesktopThreadId(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { + return id; + } + await delay(200); + } + throw new Error( + `ChatGPT Desktop conversation id did not appear on [data-response-annotation-conversation] within ${timeoutMs}ms`, + ); +} + +/** + * Prefer a durable Desktop thread id. Never returns `local:client-new-thread:*`. + */ +export function resolveDurableThreadId( + conversationId: string | null | undefined, + fallbackThreadId?: string | null, +): string | null { + if (conversationId && !isTemporaryDesktopThreadId(conversationId)) { + return toDesktopForm(conversationId); + } + if ( + fallbackThreadId + && !isTemporaryDesktopThreadId(fallbackThreadId) + && fallbackThreadId !== 'new' + ) { + return toDesktopForm(fallbackThreadId); + } + return null; +} + /** * Wait until Stop is gone and a new final-assistant marker exists. * Returns reply text + conversation id from the annotation. @@ -581,7 +692,7 @@ export async function readTurnsFromDom( x: metrics.x, y: metrics.y, deltaX: 0, - deltaY: -800, + deltaY: FULL_READ_WHEEL_DELTA_Y, }, { sessionId }, ); diff --git a/src/core/chatgpt-desktop/index.ts b/src/core/chatgpt-desktop/index.ts index 9ec1756..716a695 100644 --- a/src/core/chatgpt-desktop/index.ts +++ b/src/core/chatgpt-desktop/index.ts @@ -4,8 +4,15 @@ export { ASSISTANT_MESSAGE_SELECTOR, ATTR, COMPOSER_SELECTOR, + DEFAULT_CONVERSATION_RESOLVE_MS, + DEFAULT_FULL_READ_IDLE_WHEELS, + DEFAULT_FULL_READ_MAX_WHEELS, + DEFAULT_OPEN_TIMEOUT_MS, FINAL_ASSISTANT_SELECTOR, + FULL_READ_WHEEL_DELTA_Y, + HISTORY_GAP_PREFIX, IGNORED_TARGET_URL_MARKERS, + LOADING_TASK_TEXT, MAIN_CONTENT_SURFACE_CLASS_PREFIX, MAIN_WINDOW_URL, SELECTORS, @@ -16,6 +23,7 @@ export { isMainWindowTarget, newChatInProjectSelector, pickMainWindowTarget, + resolveDurableThreadId, summarizeTargetInfos, } from './cdp-dom.js'; export { CdpSession } from './cdp-session.js'; diff --git a/src/core/chatgpt-desktop/types.ts b/src/core/chatgpt-desktop/types.ts index 644594b..b349849 100644 --- a/src/core/chatgpt-desktop/types.ts +++ b/src/core/chatgpt-desktop/types.ts @@ -129,8 +129,14 @@ export type SendMessageResult = { readonly experimental: boolean; readonly delivery: 'accepted' | 'rejected' | 'unknown'; readonly message?: string; - /** Temporary sidebar id before reload (`local:client-new-thread:…`). */ + /** + * Temporary sidebar id before the real conversation annotation appears + * (`local:client-new-thread:…`). Never used as `threadId` once the real id + * is known from `data-response-annotation-conversation`. + */ readonly temporaryThreadId?: string; + /** Real conversation id from `data-response-annotation-conversation`. */ + readonly conversationId?: string; readonly project?: string; readonly sentVia?: 'enter' | 'button'; }; diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx index 43f13ac..d854187 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop send', description: - 'Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". Temporary sidebar ids are local:client-new-thread:… until reload — use chatgpt_desktop_wait_reply to resolve the real conversation id. Does not use app-server.', + 'Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.', annotations: { readOnlyHint: false }, inputSchema, resultSchema, diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index 2f9ddcf..b51f3c3 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -95,8 +95,11 @@ function fakeAdapter(overrides: Partial = {}): ChatGptDes }, async sendMessage({ threadId, text, project }) { return { - threadId: threadId ?? 'local:client-new-thread:deadbeef', + threadId: threadId && !threadId.startsWith('local:client-new-thread:') + ? threadId + : 'local:11111111-1111-1111-1111-111111111111', temporaryThreadId: threadId ? undefined : 'local:client-new-thread:deadbeef', + conversationId: '11111111-1111-1111-1111-111111111111', project, backend: 'cdp', experimental: false, @@ -107,7 +110,7 @@ function fakeAdapter(overrides: Partial = {}): ChatGptDes }, async waitForReply({ threadId }) { return { - threadId: threadId ?? 'conv-real-id', + threadId: 'local:conv-real-id', conversationId: 'conv-real-id', reply: 'hi there', backend: 'cdp', @@ -189,15 +192,23 @@ describe('chatgpt-desktop loopback + relaunch helpers', () => { { threadId: 'a', title: '1', pinned: false, selected: false, kind: 'local' }, { threadId: 'a', title: '1b', pinned: false, selected: true, kind: 'local' }, { threadId: 'b', title: '2', pinned: false, selected: false, kind: 'local' }, - ]).map((t) => t.threadId), - ).toEqual(['a', 'b']); + { threadId: 'local:c', title: 'c-desktop', pinned: false, selected: false, kind: 'local' }, + { threadId: 'c', title: 'c-bare', pinned: true, selected: false, kind: 'local' }, + ]).map((t) => ({ id: t.threadId, pinned: t.pinned, selected: t.selected })), + ).toEqual([ + { id: 'a', pinned: false, selected: true }, + { id: 'b', pinned: false, selected: false }, + { id: 'c', pinned: true, selected: false }, + ]); const targets = summarizeTargetInfos([ { targetId: 'overlay', type: 'page', url: 'app://-/index.html?initialRoute=%2Favatar-overlay' }, - { targetId: 'main', type: 'page', title: 'ChatGPT', url: MAIN_WINDOW_URL }, { targetId: 'web', type: 'page', url: 'https://chatgpt.com/pricing' }, + { targetId: 'main', type: 'page', title: 'ChatGPT', url: MAIN_WINDOW_URL }, ]); + // Exact URL wins regardless of /json/list-style order (overlay/web listed first). expect(pickMainWindowTarget(targets)?.targetId).toBe('main'); + expect(pickMainWindowTarget(targets.slice().reverse())?.targetId).toBe('main'); }); }); @@ -352,10 +363,15 @@ describe('chatgpt-desktop MCP tools', () => { delivery: 'accepted', backend: 'cdp', experimental: false, + threadId: 'local:11111111-1111-1111-1111-111111111111', temporaryThreadId: 'local:client-new-thread:deadbeef', + conversationId: '11111111-1111-1111-1111-111111111111', project: 'Launch', exitCode: 0, }); + expect(String((sent.structuredContent as { threadId?: string }).threadId ?? '')).not.toMatch( + /^local:client-new-thread:/, + ); const waited = await invokeMcpTool('chatgpt_desktop_wait_reply', { server: 'grok-bot', @@ -366,6 +382,7 @@ describe('chatgpt-desktop MCP tools', () => { delivery: 'replied', reply: 'hi there', conversationId: 'conv-real-id', + threadId: 'local:conv-real-id', exitCode: 0, }); }); @@ -550,7 +567,11 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () async sendMessage({ threadId, text }) { calls.push('cdp.sendMessage'); return { - threadId: threadId ?? 'local:client-new-thread:x', + threadId: threadId && !threadId.startsWith('local:client-new-thread:') + ? threadId + : 'local:resolved-after-send', + temporaryThreadId: threadId ? undefined : 'local:client-new-thread:x', + conversationId: 'resolved-after-send', backend: 'cdp', experimental: false, delivery: 'accepted' as const, @@ -560,7 +581,10 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () async waitForReply({ threadId }) { calls.push('cdp.waitForReply'); return { - threadId: threadId ?? 'unknown', + threadId: threadId && !threadId.startsWith('local:client-new-thread:') + ? threadId + : 'local:resolved-after-send', + conversationId: 'resolved-after-send', reply: 'ok', backend: 'cdp', experimental: false, @@ -1083,3 +1107,83 @@ describe('chatgpt-desktop CDP HTTP status probe', () => { } }); }); + +describe('chatgpt-desktop production-risk guards', () => { + it('never treats local:client-new-thread as a durable send/wait id', async () => { + const { resolveDurableThreadId, TEMP_THREAD_ID_PREFIX } = await import( + '../../src/core/chatgpt-desktop/cdp-dom.js' + ); + expect(resolveDurableThreadId(null, `${TEMP_THREAD_ID_PREFIX}abc`)).toBeNull(); + expect(resolveDurableThreadId(`${TEMP_THREAD_ID_PREFIX}abc`)).toBeNull(); + expect(resolveDurableThreadId('conv-real')).toBe('local:conv-real'); + expect(resolveDurableThreadId('local:conv-real', `${TEMP_THREAD_ID_PREFIX}x`)).toBe( + 'local:conv-real', + ); + }); + + it('loads history with mouseWheel (column-reverse), not scrollTop writes', async () => { + const { + FULL_READ_WHEEL_DELTA_Y, + readTurnsFromDom, + } = await import('../../src/core/chatgpt-desktop/cdp-dom.js'); + expect(FULL_READ_WHEEL_DELTA_Y).toBeLessThan(0); + + const sends: Array<{ method: string; params?: Record }> = []; + let evaluateN = 0; + const session = { + async evaluate(expression: string) { + evaluateN += 1; + if (expression.includes('scrollTop')) { + return { ok: true, x: 10, y: 20, scrollTop: 0, scrollHeight: 2000, clientHeight: 400 }; + } + // First harvest: one turn; later harvests idle so wheel loop stops. + if (evaluateN <= 2) { + return [{ turnKey: 'history-content:turn:1', role: 'assistant', text: 'hi' }]; + } + return [{ turnKey: 'history-content:turn:1', role: 'assistant', text: 'hi' }]; + }, + async send(method: string, params?: Record) { + sends.push({ method, params }); + }, + }; + + const turns = await readTurnsFromDom(session as never, 'sess', { + full: true, + limit: 10, + idleWheels: 2, + maxWheels: 3, + }); + expect(turns.length).toBeGreaterThan(0); + expect(sends.some((s) => s.method === 'Input.dispatchMouseEvent')).toBe(true); + expect( + sends.every( + (s) => + s.method !== 'Input.dispatchMouseEvent' + || (s.params?.type === 'mouseWheel' + && s.params?.deltaY === FULL_READ_WHEEL_DELTA_Y + && !('scrollTop' in (s.params ?? {}))), + ), + ).toBe(true); + }); + + it('times out when Loading task… never clears', async () => { + const { waitForLoadingTaskGone, LOADING_TASK_TEXT } = await import( + '../../src/core/chatgpt-desktop/cdp-dom.js' + ); + const session = { + async evaluate() { + return false; + }, + }; + await expect( + waitForLoadingTaskGone(session as never, 'sess', { timeoutMs: 50 }), + ).rejects.toThrow(LOADING_TASK_TEXT); + }); + + it('opens sidebar rows for both local: and bare thread ids', async () => { + const { openThreadExpression } = await import('../../src/core/chatgpt-desktop/cdp-dom.js'); + const expr = openThreadExpression('local:abc-123'); + expect(expr).toContain('local:abc-123'); + expect(expr).toContain('abc-123'); + }); +}); From 9516f370bf008e9a64794b200cfb75690b12d037 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 01:55:54 +0000 Subject: [PATCH 15/26] fix: host/modelProvider are freeform strings with dynamic discovery Zack hard requirement: no hardcoded hosts, machines, connections, or providers in schemas, enums, docs defaults, or tests beyond fixtures. host and modelProvider accept any string; descriptions point to chatgpt_desktop_list_hosts. Add a test that injects an unknown hostId into the global-state fixture and proves list_hosts + filtering work with no code change. Co-authored-by: Zack Jackson --- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 18 +-- artifact/bin/gbot.mjs | 36 ++--- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 36 ++--- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 36 ++--- docs/chatgpt-desktop-cdp.md | 15 +- src/cli/chatgpt-desktop/hosts.tsx | 2 +- src/cli/chatgpt-desktop/search.tsx | 14 +- src/cli/chatgpt-desktop/threads.tsx | 14 +- src/core/chatgpt-desktop/adapter.ts | 9 +- src/core/chatgpt-desktop/facade.ts | 12 +- src/core/chatgpt-desktop/routes.ts | 14 +- src/core/chatgpt-desktop/types.ts | 4 +- .../tools/chatgpt_desktop_list_hosts.tsx | 2 +- .../tools/chatgpt_desktop_list_threads.tsx | 8 +- .../tools/chatgpt_desktop_search_threads.tsx | 8 +- tests/route-unit/chatgpt-desktop.test.ts | 143 +++++++++++++++++- 18 files changed, 270 insertions(+), 105 deletions(-) diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 32afad4..ab3b08c 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"32b2e4be3307b3971e92791b0113ffd83dcb4ba4b8167162a8c4941789481e8e"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"1d32022b7d06a39a1183f99e325713ba05270dd651c8290099a27ce13df94df6"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"346b2d02ba1d826f5520cc69f53648c1b02499f27edea9f7d61cd20a15a401a2"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b062cef72b7632a3701dec6179f88357f3b741db6c9c364a120e4de72ea5dd9f"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"fc47b8e753000fdd32a07395bc8afe45ab9fffca0539d2aec09b8446245d5a91"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"efbfbeb3e1f1f2ad31045541b889263c92782abe5df5c955d93401418dac3686"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"fe94b3b3a90861ae02b9a886b48d0015a82fe0b7d1678ec5658253d064226df7"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"fbaeefc8572b8b0eca6b7e03a687180d20ab4d1a72174a3d3cbdc5451d79ac80"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 6a7fea3..65d43e3 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"311d86d1331309d0ab755c7c38d3b0b208c945aa30423941fe4ea4b752837337","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"6c2a2fa0d497c7e120a6adc8d3c6433535fa65ebee7577df5601543e74aaad2d","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"6a8b392ec45d4a5f70ce68fa35a285c2948c72d05671b07696b9ec9b0021cb89"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"d09018a2c8ba33d6b252a6522bb8957c5cf811c915994756126ea504747ec140"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"1c03ed7644b8006a00b751ea3b97630e008e5896c3797ef0f1cb510b941c6234"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"6f9facafa101776ce7ddf4282a4f19edcfc40b76da251afa59f8e2f4350c9f33"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"21454ac9c648e0d130d40d1f15f9e909cf5c82eafa018e7a066a419b72cb0d41"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"8be4849f9c85c392d3e989d222d714169da982c0337d57cdc3411d14084d9bf3"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"583279e0360f529405948a6fb33712dabaa9917bb616bd00dcc83a6b6422827c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"f9eb6f1333359c0523b2d4682a2ffac4dd79d0e60f5354b2e8d865443327d768"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"436567316d576e343963bcaff2086674e172bf42d4ff62a76e52e8b2d41897eb"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"9b35df3fa9a4a1655b9cb2e2f0d3b83e796648fc8d4ab3cacfa856f78e6a2df5"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"e8e1ba9c8d39307cdd1d849fb1f8e93c7c90421fcaa5eb8bbfdf9b579241f1be"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"f4843da5a5fde4728e2dfe6766be0ce29b50a45af8a9508df8fcf86dffaee651"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"8463e5a981dcc4f67b386c5f1b97504905ef9a3fc7748992af8ac4e544ed0855"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"5c8b225957262fcb281bafb82f6d89c84604fb022858737abd8cc9c8f4b5cb01"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"6f49f1cce9590831953915a8f1f8ecc3e641bc5a1230a26f35937f257393bc26"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"dfaf2ea60ea7e46be61accc91b20e591125618c83a1910ea20ed72a75322f9d8"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4d5f799e587d8d4be6e7bacb9209816c7756605f75a0595dc3d3052f04048624"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"b7a255452eb50e8b6cc3f3f589189d3c206c47395eed2aa6504d950ca7c69ea9"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"0d2d7067c8a8538fa40c6f0a68a666e65fa7a6f06f39de359e64ff30f752db5a"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"357cd413a37f173d51cacbdb6372d41b90b4d8d44787b6a2a456c7d4f4423336"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"c473cd9f3954480e3280ad5ed8eef7b135571c94e0ff0a3b7f825348406b762c"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"a33b5ff87d951e6276ec779d39392fa3050cd1ed69833accbccc9ae2576b4644"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22816,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"bbd565497cd3fd0fe527da7af6ac7a0389dce9f64944aa75ad85bc45d937b5b6"},{"bytes":1520940,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"32b2e4be3307b3971e92791b0113ffd83dcb4ba4b8167162a8c4941789481e8e"},{"bytes":2384891,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"1d32022b7d06a39a1183f99e325713ba05270dd651c8290099a27ce13df94df6"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1441603,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"346b2d02ba1d826f5520cc69f53648c1b02499f27edea9f7d61cd20a15a401a2"},{"bytes":3268118,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b062cef72b7632a3701dec6179f88357f3b741db6c9c364a120e4de72ea5dd9f"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298440,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads; --host and --model-provider are separate filters.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter: all (default) | local | hostId or friendly name","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Pass-through to app-server modelProviders (omit = all)","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Filter: all (default) | local | hostId or friendly name","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Pass-through to app-server modelProviders (omit = all)","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads; --host and --model-provider are separate filters.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host","enum":["host"],"type":"string"},"host":{"description":"Filter: all (default) | local | hostId or friendly name","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Pass-through to app-server modelProviders (omit = all)","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"54c92b7e19bd37f7db8f0c939e523bc6b14a9335bc62b383590c844d4dd59b6e","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host.","enum":["host"],"type":"string"},"host":{"description":"Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Filter passed through to app-server thread/list modelProviders. Omit for all providers.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"7ec0384da75e7531f81734aeee0078b2fc8d89ad78b6521079dcbd3b67493dc9","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"a4ca08dd2dddc2dd1ebf3a02c436e06f0b956cc854131336fa64878d719e6d2b","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"6a8b392ec45d4a5f70ce68fa35a285c2948c72d05671b07696b9ec9b0021cb89"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"ca5aec4741cb3ac4e7a4239859521e18994b49fc919a3a3bf59ce3a363ea9875"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"10081fcda493b2e0301f4f0e0dee8034f01705a60f895570224fbefa5fffa790"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"659483af940524ef155f505a0f4235ef76ed50a849a86fa1d7834256a0588838"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5ba4f07e35239c59cff2815eadb957fb13cf682d12bb25bf192f6bd8691eb4a5"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"583279e0360f529405948a6fb33712dabaa9917bb616bd00dcc83a6b6422827c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"f9eb6f1333359c0523b2d4682a2ffac4dd79d0e60f5354b2e8d865443327d768"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"436567316d576e343963bcaff2086674e172bf42d4ff62a76e52e8b2d41897eb"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"9b35df3fa9a4a1655b9cb2e2f0d3b83e796648fc8d4ab3cacfa856f78e6a2df5"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"6690338b2d0b1d1013f5d4b851ffca12e9f51fb95e791481713c658ba672e511"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"f4843da5a5fde4728e2dfe6766be0ce29b50a45af8a9508df8fcf86dffaee651"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"78de63808c3479932dff35cab0f2a9a78e84183187eb9a783823b5193b6f76c3"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"b2097d7a7811c88d74250c11dd1d5c551389f71140c12f178c60b63cc9e2dcbc"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"6f49f1cce9590831953915a8f1f8ecc3e641bc5a1230a26f35937f257393bc26"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"dfaf2ea60ea7e46be61accc91b20e591125618c83a1910ea20ed72a75322f9d8"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4d5f799e587d8d4be6e7bacb9209816c7756605f75a0595dc3d3052f04048624"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"a3d97e4e62b693a19828b5dea466505fcf2a08df705b9c302abde0990344c1d4"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"521496fdfaff13cb55f4decb9e78ebaa1d2e35e7bfcc38cc887375b200724961"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"c473cd9f3954480e3280ad5ed8eef7b135571c94e0ff0a3b7f825348406b762c"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"6c5b87b456c7a4cece6fa61ed3b4f4b0bee21e356db7b643b2838ccefbdfa4a6"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22816,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"9eeed4180d7a7c4261baf98b4b5ae66d8b9fa89558f30f0135cb57ec39d51504"},{"bytes":1521462,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"fc47b8e753000fdd32a07395bc8afe45ab9fffca0539d2aec09b8446245d5a91"},{"bytes":2385935,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"efbfbeb3e1f1f2ad31045541b889263c92782abe5df5c955d93401418dac3686"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1442545,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"fe94b3b3a90861ae02b9a886b48d0015a82fe0b7d1678ec5658253d064226df7"},{"bytes":3269060,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"fbaeefc8572b8b0eca6b7e03a687180d20ab4d1a72174a3d3cbdc5451d79ac80"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298440,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"c03763e77aa906b90f360d4a607419d90c10362bd377c16bc04688eecf36f435","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index 001889b..cb49174 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -8616,7 +8616,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.', + description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, @@ -8738,7 +8738,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Search ChatGPT Desktop threads; --host and --model-provider are separate filters.', + description: 'Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.', exitCode: 'result', positionals: [ 'query' @@ -8747,14 +8747,14 @@ var __webpack_modules__ = { additionalProperties: false, properties: { groupBy: { - description: 'Group results by host', + description: 'Group results by host (grouping mode, not a host id)', enum: [ 'host' ], type: 'string' }, host: { - description: 'Filter: all (default) | local | hostId or friendly name', + description: 'Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' }, limit: { @@ -8763,7 +8763,7 @@ var __webpack_modules__ = { type: 'number' }, modelProvider: { - description: 'Pass-through to app-server modelProviders (omit = all)', + description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' }, port: { @@ -8925,20 +8925,20 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.', + description: 'List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, properties: { groupBy: { - description: 'Group results by host', + description: 'Group results by host (grouping mode, not a host id)', enum: [ 'host' ], type: 'string' }, host: { - description: 'Filter: all (default) | local | hostId or friendly name', + description: 'Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' }, limit: { @@ -8947,7 +8947,7 @@ var __webpack_modules__ = { type: 'number' }, modelProvider: { - description: 'Pass-through to app-server modelProviders (omit = all)', + description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' }, port: { diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index cdb1c54..786f72d 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -7024,7 +7024,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.', + description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, @@ -7146,7 +7146,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Search ChatGPT Desktop threads; --host and --model-provider are separate filters.', + description: 'Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.', exitCode: 'result', positionals: [ 'query' @@ -7155,14 +7155,14 @@ var __webpack_modules__ = { additionalProperties: false, properties: { groupBy: { - description: 'Group results by host', + description: 'Group results by host (grouping mode, not a host id)', enum: [ 'host' ], type: 'string' }, host: { - description: 'Filter: all (default) | local | hostId or friendly name', + description: 'Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' }, limit: { @@ -7171,7 +7171,7 @@ var __webpack_modules__ = { type: 'number' }, modelProvider: { - description: 'Pass-through to app-server modelProviders (omit = all)', + description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' }, port: { @@ -7333,20 +7333,20 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.', + description: 'List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, properties: { groupBy: { - description: 'Group results by host', + description: 'Group results by host (grouping mode, not a host id)', enum: [ 'host' ], type: 'string' }, host: { - description: 'Filter: all (default) | local | hostId or friendly name', + description: 'Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' }, limit: { @@ -7355,7 +7355,7 @@ var __webpack_modules__ = { type: 'number' }, modelProvider: { - description: 'Pass-through to app-server modelProviders (omit = all)', + description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' }, port: { @@ -40758,7 +40758,7 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.", + "description": "Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.", "exitCode": "result", "options": [ { @@ -40834,14 +40834,14 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "Search ChatGPT Desktop threads; --host and --model-provider are separate filters.", + "description": "Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.", "exitCode": "result", "options": [ { "choices": [ "host" ], - "description": "Group results by host", + "description": "Group results by host (grouping mode, not a host id)", "key": "groupBy", "kind": "enum", "option": "group-by", @@ -40849,7 +40849,7 @@ var __webpack_modules__ = { "required": false }, { - "description": "Filter: all (default) | local | hostId or friendly name", + "description": "Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.", "key": "host", "kind": "string", "option": "host", @@ -40866,7 +40866,7 @@ var __webpack_modules__ = { "required": false }, { - "description": "Pass-through to app-server modelProviders (omit = all)", + "description": "Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.", "key": "modelProvider", "kind": "string", "option": "model-provider", @@ -40972,14 +40972,14 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.", + "description": "List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.", "exitCode": "result", "options": [ { "choices": [ "host" ], - "description": "Group results by host", + "description": "Group results by host (grouping mode, not a host id)", "key": "groupBy", "kind": "enum", "option": "group-by", @@ -40987,7 +40987,7 @@ var __webpack_modules__ = { "required": false }, { - "description": "Filter: all (default) | local | hostId or friendly name", + "description": "Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.", "key": "host", "kind": "string", "option": "host", @@ -41004,7 +41004,7 @@ var __webpack_modules__ = { "required": false }, { - "description": "Pass-through to app-server modelProviders (omit = all)", + "description": "Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.", "key": "modelProvider", "kind": "string", "option": "model-provider", diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index c210fb8..23816c1 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -11512,7 +11512,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list hosts', - description: 'Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.', + description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.', annotations: { readOnlyHint: true }, @@ -11551,7 +11551,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.', + description: 'List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.', annotations: { readOnlyHint: true }, @@ -11570,18 +11570,18 @@ var __webpack_modules__ = { }, host: { type: 'string', - description: 'Machine/location filter: "all" (default), "local", or a hostId / friendly name from chatgpt_desktop_list_hosts.' + description: 'Any string filter for machine/location. Reserved: "all" (default), "local". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.' }, modelProvider: { type: 'string', - description: 'Filter passed through to app-server thread/list modelProviders. Omit for all providers.' + description: 'Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.' }, groupBy: { type: 'string', enum: [ 'host' ], - description: 'When "host", also return groups[] keyed by host.' + description: 'When "host", also return groups[] keyed by host (grouping mode, not a host id).' } }, required: [] @@ -11668,7 +11668,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop search threads', - description: 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.', + description: 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.', annotations: { readOnlyHint: true }, @@ -11691,18 +11691,18 @@ var __webpack_modules__ = { }, host: { type: 'string', - description: 'Machine/location filter: "all" (default), "local", or a hostId / friendly name from chatgpt_desktop_list_hosts.' + description: 'Any string filter for machine/location. Reserved: "all" (default), "local". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.' }, modelProvider: { type: 'string', - description: 'Filter passed through to app-server thread/list modelProviders. Omit for all providers.' + description: 'Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.' }, groupBy: { type: 'string', enum: [ 'host' ], - description: 'When "host", also return groups[] keyed by host.' + description: 'When "host", also return groups[] keyed by host (grouping mode, not a host id).' } }, required: [ @@ -27915,7 +27915,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.", + "description": "Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -27939,19 +27939,19 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.", + "description": "List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { "groupBy": { - "description": "When \"host\", also return groups[] keyed by host.", + "description": "When \"host\", also return groups[] keyed by host (grouping mode, not a host id).", "enum": [ "host" ], "type": "string" }, "host": { - "description": "Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.", + "description": "Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.", "type": "string" }, "limit": { @@ -27959,7 +27959,7 @@ const routes = Object.freeze({ "type": "number" }, "modelProvider": { - "description": "Filter passed through to app-server thread/list modelProviders. Omit for all providers.", + "description": "Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.", "type": "string" }, "port": { @@ -28026,19 +28026,19 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.", + "description": "Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { "groupBy": { - "description": "When \"host\", also return groups[] keyed by host.", + "description": "When \"host\", also return groups[] keyed by host (grouping mode, not a host id).", "enum": [ "host" ], "type": "string" }, "host": { - "description": "Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.", + "description": "Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.", "type": "string" }, "limit": { @@ -28046,7 +28046,7 @@ const routes = Object.freeze({ "type": "number" }, "modelProvider": { - "description": "Filter passed through to app-server thread/list modelProviders. Omit for all providers.", + "description": "Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.", "type": "string" }, "port": { diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index e816dd7..e320640 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -9920,7 +9920,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list hosts', - description: 'Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.', + description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.', annotations: { readOnlyHint: true }, @@ -9959,7 +9959,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.', + description: 'List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.', annotations: { readOnlyHint: true }, @@ -9978,18 +9978,18 @@ var __webpack_modules__ = { }, host: { type: 'string', - description: 'Machine/location filter: "all" (default), "local", or a hostId / friendly name from chatgpt_desktop_list_hosts.' + description: 'Any string filter for machine/location. Reserved: "all" (default), "local". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.' }, modelProvider: { type: 'string', - description: 'Filter passed through to app-server thread/list modelProviders. Omit for all providers.' + description: 'Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.' }, groupBy: { type: 'string', enum: [ 'host' ], - description: 'When "host", also return groups[] keyed by host.' + description: 'When "host", also return groups[] keyed by host (grouping mode, not a host id).' } }, required: [] @@ -10076,7 +10076,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop search threads', - description: 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.', + description: 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.', annotations: { readOnlyHint: true }, @@ -10099,18 +10099,18 @@ var __webpack_modules__ = { }, host: { type: 'string', - description: 'Machine/location filter: "all" (default), "local", or a hostId / friendly name from chatgpt_desktop_list_hosts.' + description: 'Any string filter for machine/location. Reserved: "all" (default), "local". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.' }, modelProvider: { type: 'string', - description: 'Filter passed through to app-server thread/list modelProviders. Omit for all providers.' + description: 'Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.' }, groupBy: { type: 'string', enum: [ 'host' ], - description: 'When "host", also return groups[] keyed by host.' + description: 'When "host", also return groups[] keyed by host (grouping mode, not a host id).' } }, required: [ @@ -59427,7 +59427,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.", + "description": "Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -59450,19 +59450,19 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.", + "description": "List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { "groupBy": { - "description": "When \"host\", also return groups[] keyed by host.", + "description": "When \"host\", also return groups[] keyed by host (grouping mode, not a host id).", "enum": [ "host" ], "type": "string" }, "host": { - "description": "Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.", + "description": "Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.", "type": "string" }, "limit": { @@ -59470,7 +59470,7 @@ var __webpack_modules__ = { "type": "number" }, "modelProvider": { - "description": "Filter passed through to app-server thread/list modelProviders. Omit for all providers.", + "description": "Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.", "type": "string" }, "port": { @@ -59535,19 +59535,19 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.", + "description": "Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { "groupBy": { - "description": "When \"host\", also return groups[] keyed by host.", + "description": "When \"host\", also return groups[] keyed by host (grouping mode, not a host id).", "enum": [ "host" ], "type": "string" }, "host": { - "description": "Machine/location filter: \"all\" (default), \"local\", or a hostId / friendly name from chatgpt_desktop_list_hosts.", + "description": "Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.", "type": "string" }, "limit": { @@ -59555,7 +59555,7 @@ var __webpack_modules__ = { "type": "number" }, "modelProvider": { - "description": "Filter passed through to app-server thread/list modelProviders. Omit for all providers.", + "description": "Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.", "type": "string" }, "port": { diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index ca12191..d3dd6a7 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -31,16 +31,19 @@ Override the port with `CHATGPT_DESKTOP_CDP_PORT` or `--port`. ```sh gbot chatgpt-desktop status -gbot chatgpt-desktop hosts +gbot chatgpt-desktop hosts # discover hostIds + modelProviders at runtime gbot chatgpt-desktop threads --limit 20 gbot chatgpt-desktop threads --host local -gbot chatgpt-desktop threads --host macbook --model-provider openai +gbot chatgpt-desktop threads --host --model-provider gbot chatgpt-desktop search "launch" --host all gbot chatgpt-desktop read gbot chatgpt-desktop send --thread-id "hello" gbot chatgpt-desktop send "start a new chat with this text" ``` +`--host` / `--model-provider` accept **any string** (not enums). Discover +allowed values with `gbot chatgpt-desktop hosts` / `chatgpt_desktop_list_hosts`. + ## MCP tools | Tool | Role | @@ -96,10 +99,12 @@ list filter, not a field. `chatgpt_desktop_list_threads` / search take two independent filters: -| Filter | Values | Default | Effect | +| Filter | Values (any string — not an enum) | Default | Effect | | --- | --- | --- | --- | -| `host` | `all` \| `local` \| `` | `all` | Machine/location from remote summaries + local | -| `modelProvider` | provider id string | omit / `[]` = all | Passed through to app-server `modelProviders` | +| `host` | `all` \| `local` \| any hostId / friendly name from `list_hosts` | `all` | Machine/location from remote summaries + local | +| `modelProvider` | any provider id from `list_hosts` | omit / `[]` = all | Passed through to app-server `modelProviders` | + +New machines or connections appear in `list_hosts` with **no code change**. Optional `groupBy: "host"` returns `groups[]` keyed by host. diff --git a/src/cli/chatgpt-desktop/hosts.tsx b/src/cli/chatgpt-desktop/hosts.tsx index d9afd93..ba4d5ee 100644 --- a/src/cli/chatgpt-desktop/hosts.tsx +++ b/src/cli/chatgpt-desktop/hosts.tsx @@ -10,7 +10,7 @@ import { export const config = { description: - 'List discovered ChatGPT Desktop hosts (local + remote-thread-summaries-v3) with thread counts, friendly names, and modelProviders.', + 'Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, diff --git a/src/cli/chatgpt-desktop/search.tsx b/src/cli/chatgpt-desktop/search.tsx index ebb8545..da6bded 100644 --- a/src/cli/chatgpt-desktop/search.tsx +++ b/src/cli/chatgpt-desktop/search.tsx @@ -10,20 +10,26 @@ import { export const config = { description: - 'Search ChatGPT Desktop threads; --host and --model-provider are separate filters.', + 'Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.', exitCode: 'result', positionals: ['query'], inputJsonSchema: { additionalProperties: false, properties: { - groupBy: { description: 'Group results by host', enum: ['host'], type: 'string' }, + groupBy: { + description: 'Group results by host (grouping mode, not a host id)', + enum: ['host'], + type: 'string', + }, host: { - description: 'Filter: all (default) | local | hostId or friendly name', + description: + 'Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string', }, limit: { default: 50, description: 'Max matches (1-200)', type: 'number' }, modelProvider: { - description: 'Pass-through to app-server modelProviders (omit = all)', + description: + 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string', }, port: { description: 'Local CDP port', type: 'number' }, diff --git a/src/cli/chatgpt-desktop/threads.tsx b/src/cli/chatgpt-desktop/threads.tsx index 6fc3d5e..7405d6e 100644 --- a/src/cli/chatgpt-desktop/threads.tsx +++ b/src/cli/chatgpt-desktop/threads.tsx @@ -10,19 +10,25 @@ import { export const config = { description: - 'List local + remote-control ChatGPT Desktop threads; --host and --model-provider are separate filters.', + 'List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, properties: { - groupBy: { description: 'Group results by host', enum: ['host'], type: 'string' }, + groupBy: { + description: 'Group results by host (grouping mode, not a host id)', + enum: ['host'], + type: 'string', + }, host: { - description: 'Filter: all (default) | local | hostId or friendly name', + description: + 'Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string', }, limit: { default: 50, description: 'Max threads (1-200)', type: 'number' }, modelProvider: { - description: 'Pass-through to app-server modelProviders (omit = all)', + description: + 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string', }, port: { description: 'Local CDP port', type: 'number' }, diff --git a/src/core/chatgpt-desktop/adapter.ts b/src/core/chatgpt-desktop/adapter.ts index 9d4d89e..aa8c625 100644 --- a/src/core/chatgpt-desktop/adapter.ts +++ b/src/core/chatgpt-desktop/adapter.ts @@ -18,9 +18,9 @@ export interface ChatGptDesktopAdapter { listTargets(): Promise; listThreads(options?: { limit?: number; - /** `all` (default) | `local` | hostId / friendly name. */ + /** Any string: `all` (default) | `local` | hostId / friendly name from list_hosts. Not an enum. */ host?: string; - /** Passed through to app-server `modelProviders` (omit/empty = all). */ + /** Any modelProvider id (app-server modelProviders). Omit = all. See list_hosts. Not an enum. */ modelProvider?: string; groupBy?: 'host'; }): Promise; @@ -28,14 +28,17 @@ export interface ChatGptDesktopAdapter { searchThreads?(options: { query: string; limit?: number; + /** Any string; see list_hosts. Not an enum. */ host?: string; + /** Any modelProvider id; see list_hosts. Not an enum. */ modelProvider?: string; groupBy?: 'host'; }): Promise; /** * Optional; facades that discover remote-control hosts implement this. * Returns `local` + every `remote-thread-summaries-v3:` host with - * counts / friendly names, plus discovered `modelProviders`. + * counts / friendly names, plus discovered `modelProviders`. Never hardcode + * those ids — new machines/connections appear with no code change. */ listHosts?(): Promise; readThread(options: { diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index 7d2612b..04f70b1 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -55,16 +55,18 @@ const defaultFallbacks: ChatGptDesktopFallbacks = { export type ListThreadsOptions = { limit?: number; /** - * Machine / location filter discovered from remote summaries + `local`. - * `all` (default) | `local` | ``. + * Any string (not an enum). Reserved: `all` (default), `local`. Otherwise a + * hostId or friendly name discovered at runtime — see `listHosts` / + * `chatgpt_desktop_list_hosts`. New machines appear with no code change. */ host?: string; /** - * Passed through to app-server `thread/list` as `modelProviders`. - * Omit / empty = all providers (`modelProviders: []`). + * Any modelProvider id string (not an enum). Passed through to app-server + * `thread/list` as `modelProviders`. Omit / empty = all. Discovered values: + * see `listHosts` / `chatgpt_desktop_list_hosts`. */ modelProvider?: string; - /** When `"host"`, also return `groups` keyed by host. */ + /** When `"host"`, also return `groups` keyed by host (grouping mode). */ groupBy?: 'host'; }; diff --git a/src/core/chatgpt-desktop/routes.ts b/src/core/chatgpt-desktop/routes.ts index 2c5b349..258651f 100644 --- a/src/core/chatgpt-desktop/routes.ts +++ b/src/core/chatgpt-desktop/routes.ts @@ -17,9 +17,17 @@ export const listThreadsSchema = z .object({ port: z.number().int().min(1).max(65535).optional(), limit: z.number().int().min(1).max(200).default(50), - /** `all` (default) | `local` | hostId / friendly name. */ + /** + * Any string. Reserved: `all` (default), `local`. Otherwise a hostId or + * friendly name discovered at runtime — see `chatgpt_desktop_list_hosts`. + * Not an enum; new machines appear with no code change. + */ host: z.string().min(1).max(256).optional(), - /** Passed through to app-server `modelProviders` (omit = all). */ + /** + * Any modelProvider id string (passed through as app-server + * `modelProviders`). Omit for all. Discovered values: see + * `chatgpt_desktop_list_hosts`. Not an enum. + */ modelProvider: z.string().min(1).max(256).optional(), groupBy: z.literal('host').optional(), }) @@ -30,7 +38,9 @@ export const searchThreadsSchema = z port: z.number().int().min(1).max(65535).optional(), query: z.string().min(1).max(512), limit: z.number().int().min(1).max(200).default(50), + /** Any string; see `chatgpt_desktop_list_hosts`. Not an enum. */ host: z.string().min(1).max(256).optional(), + /** Any modelProvider id; see `chatgpt_desktop_list_hosts`. Not an enum. */ modelProvider: z.string().min(1).max(256).optional(), groupBy: z.literal('host').optional(), }) diff --git a/src/core/chatgpt-desktop/types.ts b/src/core/chatgpt-desktop/types.ts index b349849..19f8f1c 100644 --- a/src/core/chatgpt-desktop/types.ts +++ b/src/core/chatgpt-desktop/types.ts @@ -86,9 +86,9 @@ export type ListThreadsResult = { readonly limit: number; readonly nextCursor?: string | null; readonly query?: string; - /** Host filter applied: `all` | `local` | hostId / friendly name. */ + /** Host filter applied: any string (`all` | `local` | hostId / friendly name from list_hosts). */ readonly host?: string; - /** Model-provider filter passed through to app-server `modelProviders`. */ + /** Model-provider filter (any string; see list_hosts). Passed through to app-server `modelProviders`. */ readonly modelProvider?: string; readonly groupBy?: 'host'; /** Present when `groupBy: "host"`. */ diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx index e313506..d15dd9e 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list hosts', description: - 'Discover ChatGPT Desktop hosts dynamically: always includes local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts). Also reports modelProviders discovered via an app-server list method when present, otherwise distinct modelProvider values from thread/list. Use this instead of hardcoding host ids. Result includes hostsSource and modelProvidersSource.', + 'Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx index 9b70d3f..d8c7d9a 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list threads', description: - 'List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters: host (all|local|, default all) and modelProvider (passed through as modelProviders; omit/empty = all). Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.', + 'List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -26,17 +26,17 @@ export default defineTool( host: { type: 'string', description: - 'Machine/location filter: "all" (default), "local", or a hostId / friendly name from chatgpt_desktop_list_hosts.', + 'Any string filter for machine/location. Reserved: "all" (default), "local". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.', }, modelProvider: { type: 'string', description: - 'Filter passed through to app-server thread/list modelProviders. Omit for all providers.', + 'Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.', }, groupBy: { type: 'string', enum: ['host'], - description: 'When "host", also return groups[] keyed by host.', + description: 'When "host", also return groups[] keyed by host (grouping mode, not a host id).', }, }, required: [], diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx index 3bddf19..9f8bfe7 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop search threads', description: - 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters: host (all|local|) and modelProvider (app-server modelProviders pass-through). Optional groupBy=host. Discover hosts via chatgpt_desktop_list_hosts. Result includes backend.', + 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -27,17 +27,17 @@ export default defineTool( host: { type: 'string', description: - 'Machine/location filter: "all" (default), "local", or a hostId / friendly name from chatgpt_desktop_list_hosts.', + 'Any string filter for machine/location. Reserved: "all" (default), "local". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.', }, modelProvider: { type: 'string', description: - 'Filter passed through to app-server thread/list modelProviders. Omit for all providers.', + 'Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.', }, groupBy: { type: 'string', enum: ['host'], - description: 'When "host", also return groups[] keyed by host.', + description: 'When "host", also return groups[] keyed by host (grouping mode, not a host id).', }, }, required: ['query'], diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index b51f3c3..cbc5ac1 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -60,16 +60,18 @@ function fakeAdapter(overrides: Partial = {}): ChatGptDes }; }, async listHosts() { + // Stub only — production discovery is dynamic (see listDiscoveredHosts / + // chatgpt_desktop_list_hosts). Do not treat these ids as an allowlist. return { backend: 'app-server' as const, hostsSource: 'remote-thread-summaries-v3+local', - modelProviders: ['openai'], + modelProviders: ['fixture-provider'], modelProvidersSource: 'thread/list-distinct', hosts: [ { hostId: 'local', hostName: 'local', location: 'local' as const, threadCount: 1 }, { - hostId: 'host-macbook', - hostName: "Zack's MacBook", + hostId: 'fixture-remote-a', + hostName: 'Fixture Remote A', location: 'remote' as const, threadCount: 2, }, @@ -325,10 +327,10 @@ describe('chatgpt-desktop MCP tools', () => { exitCode: 0, hostsSource: 'remote-thread-summaries-v3+local', modelProvidersSource: 'thread/list-distinct', - modelProviders: ['openai'], + modelProviders: ['fixture-provider'], hosts: [ { hostId: 'local', location: 'local' }, - { hostId: 'host-macbook', hostName: "Zack's MacBook" }, + { hostId: 'fixture-remote-a', hostName: 'Fixture Remote A' }, ], }); @@ -1047,6 +1049,137 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () expect(err.message).toMatch(/app-server/); }); + it('discovers an unknown hostId from global-state and filters by it with no code change', async () => { + const { copyFileSync, mkdtempSync, readFileSync, writeFileSync } = await import('node:fs'); + const { tmpdir } = await import('node:os'); + const { join } = await import('node:path'); + const { randomUUID } = await import('node:crypto'); + const { + finalizeThreadList, + listDiscoveredHosts, + listRemoteThreadsFromState, + } = await import('../../src/core/chatgpt-desktop/index.js'); + + // Brand-new id never mentioned in source — only injected into the fixture. + const unknownHostId = `host-supercomputer-${randomUUID().slice(0, 8)}`; + const unknownFriendly = 'Supercomputer Lab 9000'; + const unknownThreadId = randomUUID(); + + const home = mkdtempSync(join(tmpdir(), 'gbot-remote-unknown-')); + const fixturePath = join(process.cwd(), 'tests/fixtures/codex-global-state-remote.json'); + const statePath = join(home, '.codex-global-state.json'); + const base = JSON.parse(readFileSync(fixturePath, 'utf8')) as Record; + const hostsV1 = (base['remote-hosts-v1'] ?? {}) as Record; + hostsV1[unknownHostId] = { name: unknownFriendly, envName: 'lab' }; + base['remote-hosts-v1'] = hostsV1; + base[`remote-thread-summaries-v3:${unknownHostId}`] = { + hostName: unknownFriendly, + threads: [ + { + id: unknownThreadId, + title: 'Brand new machine thread', + updatedAt: 1700000999, + modelProvider: 'brand-new-provider', + }, + ], + }; + writeFileSync(statePath, JSON.stringify(base, null, 2)); + // Keep a copy of the stock fixture nearby so the test still proves we + // started from fixture data and only added the unknown host. + copyFileSync(fixturePath, join(home, 'stock-fixture.json')); + + const env = { CODEX_HOME: home }; + const remotes = listRemoteThreadsFromState(env); + expect(remotes.some((t) => t.hostId === unknownHostId)).toBe(true); + + const discovered = listDiscoveredHosts(env, { localThreadCount: 0 }); + expect(discovered.map((h) => h.hostId)).toContain(unknownHostId); + expect(discovered.find((h) => h.hostId === unknownHostId)).toMatchObject({ + hostId: unknownHostId, + hostName: unknownFriendly, + location: 'remote', + threadCount: 1, + }); + + const filtered = finalizeThreadList( + { + backend: 'app-server', + limit: 50, + threads: [ + { + threadId: 'local:local-thread-1', + title: 'Local only', + pinned: false, + selected: false, + kind: 'codex', + location: 'local', + hostId: null, + hostName: null, + }, + ], + }, + { limit: 50, remotes, host: unknownHostId }, + ); + expect(filtered.host).toBe(unknownHostId); + expect(filtered.threads.length).toBeGreaterThan(0); + expect(filtered.threads.every((t) => t.hostId === unknownHostId)).toBe(true); + + const byFriendly = finalizeThreadList( + { + backend: 'app-server', + limit: 50, + threads: [], + }, + { limit: 50, remotes, host: 'Supercomputer Lab' }, + ); + expect(byFriendly.threads.every((t) => t.hostId === unknownHostId)).toBe(true); + expect(byFriendly.threads.length).toBeGreaterThan(0); + + const facade = new ChatGptDesktopFacade( + fakeAdapter({ + async connect() { + throw new CdpUnreachableError('offline'); + }, + async listThreads() { + throw new CdpUnreachableError('offline'); + }, + }), + 9222, + { + listThreads: async ({ limit = 50 } = {}) => ({ + backend: 'app-server' as const, + limit, + threads: [], + }), + searchThreads: async () => ({ + backend: 'app-server' as const, + limit: 1, + query: '', + threads: [], + }), + readThread: async () => { + throw new Error('unused'); + }, + statusProbe: async () => ({ reachable: true, mode: 'daemon' }), + listRemoteThreads: () => remotes, + discoverModelProviders: async () => ({ + providers: ['brand-new-provider'], + source: 'thread/list-distinct' as const, + }), + discoverRemoteEnvironments: async () => ({ hosts: [], source: null }), + listHosts: (processEnv, opts) => listDiscoveredHosts(env, opts), + }, + ); + const hostList = await facade.listHosts(); + expect(hostList.hosts.some((h) => h.hostId === unknownHostId)).toBe(true); + expect(hostList.hosts.find((h) => h.hostId === unknownHostId)).toMatchObject({ + hostName: unknownFriendly, + threadCount: 1, + location: 'remote', + }); + expect(hostList.modelProviders).toContain('brand-new-provider'); + }); + it('skips malformed global-state files without throwing', async () => { const { mkdtempSync, writeFileSync } = await import('node:fs'); const { tmpdir } = await import('node:os'); From 323e8e1c1969bd3e4d52c1fb8dbb13c8ac13f303 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 01:59:22 +0000 Subject: [PATCH 16/26] chore: regenerate artifact manifest after rebase onto main Rebased onto main (#114 verify retry + #96 @rstest/core 0.12.2) and rebuilt agent-bundle artifacts so the committed snapshot matches source. Co-authored-by: Zack Jackson --- artifact/agent-bundle.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 65d43e3..e772edf 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"7ec0384da75e7531f81734aeee0078b2fc8d89ad78b6521079dcbd3b67493dc9","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"a4ca08dd2dddc2dd1ebf3a02c436e06f0b956cc854131336fa64878d719e6d2b","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"6a8b392ec45d4a5f70ce68fa35a285c2948c72d05671b07696b9ec9b0021cb89"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"d83f12f7ebebf59d1d17bc1a800e1de5c96791ea8155406d43a5b59aeabdaaf8"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"ca5aec4741cb3ac4e7a4239859521e18994b49fc919a3a3bf59ce3a363ea9875"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"3652dcd8f5875437733a75a06aad3355d020352deb000aa879f67b481d036745"},{"executable":false,"path":"package.json","sha256":"a8cf92c2512335e75bf01c53f3bf15b44f51fb9bc5635466bfd47d2f8cba133e"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"10081fcda493b2e0301f4f0e0dee8034f01705a60f895570224fbefa5fffa790"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"659483af940524ef155f505a0f4235ef76ed50a849a86fa1d7834256a0588838"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5ba4f07e35239c59cff2815eadb957fb13cf682d12bb25bf192f6bd8691eb4a5"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"583279e0360f529405948a6fb33712dabaa9917bb616bd00dcc83a6b6422827c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"f9eb6f1333359c0523b2d4682a2ffac4dd79d0e60f5354b2e8d865443327d768"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"436567316d576e343963bcaff2086674e172bf42d4ff62a76e52e8b2d41897eb"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"9b35df3fa9a4a1655b9cb2e2f0d3b83e796648fc8d4ab3cacfa856f78e6a2df5"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"6690338b2d0b1d1013f5d4b851ffca12e9f51fb95e791481713c658ba672e511"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"f4843da5a5fde4728e2dfe6766be0ce29b50a45af8a9508df8fcf86dffaee651"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"78de63808c3479932dff35cab0f2a9a78e84183187eb9a783823b5193b6f76c3"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"b2097d7a7811c88d74250c11dd1d5c551389f71140c12f178c60b63cc9e2dcbc"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"6f49f1cce9590831953915a8f1f8ecc3e641bc5a1230a26f35937f257393bc26"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"dfaf2ea60ea7e46be61accc91b20e591125618c83a1910ea20ed72a75322f9d8"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4d5f799e587d8d4be6e7bacb9209816c7756605f75a0595dc3d3052f04048624"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"a3d97e4e62b693a19828b5dea466505fcf2a08df705b9c302abde0990344c1d4"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"521496fdfaff13cb55f4decb9e78ebaa1d2e35e7bfcc38cc887375b200724961"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"c473cd9f3954480e3280ad5ed8eef7b135571c94e0ff0a3b7f825348406b762c"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"6c5b87b456c7a4cece6fa61ed3b4f4b0bee21e356db7b643b2838ccefbdfa4a6"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22816,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"9eeed4180d7a7c4261baf98b4b5ae66d8b9fa89558f30f0135cb57ec39d51504"},{"bytes":1521462,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"fc47b8e753000fdd32a07395bc8afe45ab9fffca0539d2aec09b8446245d5a91"},{"bytes":2385935,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"efbfbeb3e1f1f2ad31045541b889263c92782abe5df5c955d93401418dac3686"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1442545,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"fe94b3b3a90861ae02b9a886b48d0015a82fe0b7d1678ec5658253d064226df7"},{"bytes":3269060,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"fbaeefc8572b8b0eca6b7e03a687180d20ab4d1a72174a3d3cbdc5451d79ac80"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298440,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"c03763e77aa906b90f360d4a607419d90c10362bd377c16bc04688eecf36f435","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"7ec0384da75e7531f81734aeee0078b2fc8d89ad78b6521079dcbd3b67493dc9","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"1b2c795fa8b4aafc31d03de3de27da7bc6af87643c600c776edb05b77a0aa39d","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"6a8b392ec45d4a5f70ce68fa35a285c2948c72d05671b07696b9ec9b0021cb89"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"ca5aec4741cb3ac4e7a4239859521e18994b49fc919a3a3bf59ce3a363ea9875"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"10081fcda493b2e0301f4f0e0dee8034f01705a60f895570224fbefa5fffa790"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"659483af940524ef155f505a0f4235ef76ed50a849a86fa1d7834256a0588838"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5ba4f07e35239c59cff2815eadb957fb13cf682d12bb25bf192f6bd8691eb4a5"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"583279e0360f529405948a6fb33712dabaa9917bb616bd00dcc83a6b6422827c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"f9eb6f1333359c0523b2d4682a2ffac4dd79d0e60f5354b2e8d865443327d768"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"436567316d576e343963bcaff2086674e172bf42d4ff62a76e52e8b2d41897eb"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"9b35df3fa9a4a1655b9cb2e2f0d3b83e796648fc8d4ab3cacfa856f78e6a2df5"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"6690338b2d0b1d1013f5d4b851ffca12e9f51fb95e791481713c658ba672e511"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"f4843da5a5fde4728e2dfe6766be0ce29b50a45af8a9508df8fcf86dffaee651"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"78de63808c3479932dff35cab0f2a9a78e84183187eb9a783823b5193b6f76c3"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"d260ca3a9d150900cc1a2e4f3df2e8f3712714ed9be2ecd6a646eda6e7b1b8d4"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"6f49f1cce9590831953915a8f1f8ecc3e641bc5a1230a26f35937f257393bc26"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"dfaf2ea60ea7e46be61accc91b20e591125618c83a1910ea20ed72a75322f9d8"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4d5f799e587d8d4be6e7bacb9209816c7756605f75a0595dc3d3052f04048624"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"a3d97e4e62b693a19828b5dea466505fcf2a08df705b9c302abde0990344c1d4"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"521496fdfaff13cb55f4decb9e78ebaa1d2e35e7bfcc38cc887375b200724961"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"c473cd9f3954480e3280ad5ed8eef7b135571c94e0ff0a3b7f825348406b762c"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"6c5b87b456c7a4cece6fa61ed3b4f4b0bee21e356db7b643b2838ccefbdfa4a6"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22816,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"9eeed4180d7a7c4261baf98b4b5ae66d8b9fa89558f30f0135cb57ec39d51504"},{"bytes":1521462,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"fc47b8e753000fdd32a07395bc8afe45ab9fffca0539d2aec09b8446245d5a91"},{"bytes":2385935,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"efbfbeb3e1f1f2ad31045541b889263c92782abe5df5c955d93401418dac3686"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1442545,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"fe94b3b3a90861ae02b9a886b48d0015a82fe0b7d1678ec5658253d064226df7"},{"bytes":3269060,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"fbaeefc8572b8b0eca6b7e03a687180d20ab4d1a72174a3d3cbdc5451d79ac80"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298440,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"c03763e77aa906b90f360d4a607419d90c10362bd377c16bc04688eecf36f435","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} From 6b1cf363efaabc4e2ed409ef7557a6a15f48d5c0 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 02:02:11 +0000 Subject: [PATCH 17/26] test: include chatgpt_desktop_list_hosts in MCP tool inventory Package CI failed because tools.test.ts still expected the pre-list_hosts tool set after rebase. Co-authored-by: Zack Jackson --- tests/route-unit/tools.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/route-unit/tools.test.ts b/tests/route-unit/tools.test.ts index 260ce35..bfe9d43 100644 --- a/tests/route-unit/tools.test.ts +++ b/tests/route-unit/tools.test.ts @@ -133,7 +133,7 @@ beforeEach(() => { describe('grok-bot MCP server', () => { it('registers messaging, conversation and managed bridge tools', async () => { const surface = await listMcpSurface({ server: 'grok-bot' }); - expect([...surface.tools].sort()).toEqual(['chatgpt_desktop_list_threads', 'chatgpt_desktop_read_thread', 'chatgpt_desktop_search_threads', 'chatgpt_desktop_send', 'chatgpt_desktop_status', 'chatgpt_desktop_wait_reply', 'claude_send', 'codex_send', 'codex_threads', 'codex_wait', 'codex_watch', 'gbot_bridge_start', 'gbot_bridge_status', 'gbot_bridge_stop', 'gbot_codex_respond', 'gbot_grok_approvals', 'gbot_grok_respond', 'gbot_send', 'gbot_thread']); + expect([...surface.tools].sort()).toEqual(['chatgpt_desktop_list_hosts', 'chatgpt_desktop_list_threads', 'chatgpt_desktop_read_thread', 'chatgpt_desktop_search_threads', 'chatgpt_desktop_send', 'chatgpt_desktop_status', 'chatgpt_desktop_wait_reply', 'claude_send', 'codex_send', 'codex_threads', 'codex_wait', 'codex_watch', 'gbot_bridge_start', 'gbot_bridge_status', 'gbot_bridge_stop', 'gbot_codex_respond', 'gbot_grok_approvals', 'gbot_grok_respond', 'gbot_send', 'gbot_thread']); }); it('lists and responds to an exact current Grok approval through the native API', async () => { From e5058cb90fd2ce2a43ce86f67bf24d6cdf41c39c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 02:03:52 +0000 Subject: [PATCH 18/26] chore: refresh artifact source snapshot after tools.test fix The package CI snapshot check requires the committed manifest sourceInputs hash to match tests/route-unit/tools.test.ts. Co-authored-by: Zack Jackson --- artifact/agent-bundle.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index e772edf..1a6caff 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"7ec0384da75e7531f81734aeee0078b2fc8d89ad78b6521079dcbd3b67493dc9","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"1b2c795fa8b4aafc31d03de3de27da7bc6af87643c600c776edb05b77a0aa39d","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"6a8b392ec45d4a5f70ce68fa35a285c2948c72d05671b07696b9ec9b0021cb89"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"ca5aec4741cb3ac4e7a4239859521e18994b49fc919a3a3bf59ce3a363ea9875"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"10081fcda493b2e0301f4f0e0dee8034f01705a60f895570224fbefa5fffa790"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"659483af940524ef155f505a0f4235ef76ed50a849a86fa1d7834256a0588838"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5ba4f07e35239c59cff2815eadb957fb13cf682d12bb25bf192f6bd8691eb4a5"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"583279e0360f529405948a6fb33712dabaa9917bb616bd00dcc83a6b6422827c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"f9eb6f1333359c0523b2d4682a2ffac4dd79d0e60f5354b2e8d865443327d768"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"436567316d576e343963bcaff2086674e172bf42d4ff62a76e52e8b2d41897eb"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"9b35df3fa9a4a1655b9cb2e2f0d3b83e796648fc8d4ab3cacfa856f78e6a2df5"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"6690338b2d0b1d1013f5d4b851ffca12e9f51fb95e791481713c658ba672e511"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"f4843da5a5fde4728e2dfe6766be0ce29b50a45af8a9508df8fcf86dffaee651"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"78de63808c3479932dff35cab0f2a9a78e84183187eb9a783823b5193b6f76c3"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"d260ca3a9d150900cc1a2e4f3df2e8f3712714ed9be2ecd6a646eda6e7b1b8d4"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"6f49f1cce9590831953915a8f1f8ecc3e641bc5a1230a26f35937f257393bc26"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"dfaf2ea60ea7e46be61accc91b20e591125618c83a1910ea20ed72a75322f9d8"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4d5f799e587d8d4be6e7bacb9209816c7756605f75a0595dc3d3052f04048624"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"a3d97e4e62b693a19828b5dea466505fcf2a08df705b9c302abde0990344c1d4"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"521496fdfaff13cb55f4decb9e78ebaa1d2e35e7bfcc38cc887375b200724961"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"c473cd9f3954480e3280ad5ed8eef7b135571c94e0ff0a3b7f825348406b762c"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"6c5b87b456c7a4cece6fa61ed3b4f4b0bee21e356db7b643b2838ccefbdfa4a6"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"ffa72b480e29a6d777d65fd406351fc84217ac1744b57390ed448677c3911a77"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22816,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"9eeed4180d7a7c4261baf98b4b5ae66d8b9fa89558f30f0135cb57ec39d51504"},{"bytes":1521462,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"fc47b8e753000fdd32a07395bc8afe45ab9fffca0539d2aec09b8446245d5a91"},{"bytes":2385935,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"efbfbeb3e1f1f2ad31045541b889263c92782abe5df5c955d93401418dac3686"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1442545,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"fe94b3b3a90861ae02b9a886b48d0015a82fe0b7d1678ec5658253d064226df7"},{"bytes":3269060,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"fbaeefc8572b8b0eca6b7e03a687180d20ab4d1a72174a3d3cbdc5451d79ac80"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298440,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"c03763e77aa906b90f360d4a607419d90c10362bd377c16bc04688eecf36f435","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"7ec0384da75e7531f81734aeee0078b2fc8d89ad78b6521079dcbd3b67493dc9","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"3b77f5581c9ee6ec5413cd08d2d5ae895cdc7e60b9f036ed6e5206fc713c4c26","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"6a8b392ec45d4a5f70ce68fa35a285c2948c72d05671b07696b9ec9b0021cb89"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"ca5aec4741cb3ac4e7a4239859521e18994b49fc919a3a3bf59ce3a363ea9875"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"10081fcda493b2e0301f4f0e0dee8034f01705a60f895570224fbefa5fffa790"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"659483af940524ef155f505a0f4235ef76ed50a849a86fa1d7834256a0588838"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5ba4f07e35239c59cff2815eadb957fb13cf682d12bb25bf192f6bd8691eb4a5"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"583279e0360f529405948a6fb33712dabaa9917bb616bd00dcc83a6b6422827c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"f9eb6f1333359c0523b2d4682a2ffac4dd79d0e60f5354b2e8d865443327d768"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"436567316d576e343963bcaff2086674e172bf42d4ff62a76e52e8b2d41897eb"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"9b35df3fa9a4a1655b9cb2e2f0d3b83e796648fc8d4ab3cacfa856f78e6a2df5"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"6690338b2d0b1d1013f5d4b851ffca12e9f51fb95e791481713c658ba672e511"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"f4843da5a5fde4728e2dfe6766be0ce29b50a45af8a9508df8fcf86dffaee651"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"78de63808c3479932dff35cab0f2a9a78e84183187eb9a783823b5193b6f76c3"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"d260ca3a9d150900cc1a2e4f3df2e8f3712714ed9be2ecd6a646eda6e7b1b8d4"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"6f49f1cce9590831953915a8f1f8ecc3e641bc5a1230a26f35937f257393bc26"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"dfaf2ea60ea7e46be61accc91b20e591125618c83a1910ea20ed72a75322f9d8"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4d5f799e587d8d4be6e7bacb9209816c7756605f75a0595dc3d3052f04048624"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"a3d97e4e62b693a19828b5dea466505fcf2a08df705b9c302abde0990344c1d4"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"521496fdfaff13cb55f4decb9e78ebaa1d2e35e7bfcc38cc887375b200724961"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"c473cd9f3954480e3280ad5ed8eef7b135571c94e0ff0a3b7f825348406b762c"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"6c5b87b456c7a4cece6fa61ed3b4f4b0bee21e356db7b643b2838ccefbdfa4a6"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"b671db62ea723a21e11f69ba4b857e271573db22dd61aeb1d152b989824df5cb"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22816,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"9eeed4180d7a7c4261baf98b4b5ae66d8b9fa89558f30f0135cb57ec39d51504"},{"bytes":1521462,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"fc47b8e753000fdd32a07395bc8afe45ab9fffca0539d2aec09b8446245d5a91"},{"bytes":2385935,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"efbfbeb3e1f1f2ad31045541b889263c92782abe5df5c955d93401418dac3686"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1442545,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"fe94b3b3a90861ae02b9a886b48d0015a82fe0b7d1678ec5658253d064226df7"},{"bytes":3269060,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"fbaeefc8572b8b0eca6b7e03a687180d20ab4d1a72174a3d3cbdc5451d79ac80"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298440,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"c03763e77aa906b90f360d4a607419d90c10362bd377c16bc04688eecf36f435","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} From c561a03dedd91aa5bcd3b0ca1209bc09c430cec4 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 28 Sep 2026 19:24:58 -0700 Subject: [PATCH 19/26] Fix Desktop CDP isolation, reply tracking, and dynamic thread inventory --- .changeset/chatgpt-desktop-cdp.md | 2 + artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 672 +++++++---------- artifact/bin/gbot.mjs | 676 +++++++----------- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 672 +++++++---------- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 672 +++++++---------- artifact/scripts/gbot-relay.mjs | 15 +- docs/chatgpt-desktop-cdp.md | 40 +- src/cli/chatgpt-desktop/hosts.tsx | 2 +- src/cli/chatgpt-desktop/send.tsx | 2 +- .../chatgpt-desktop/app-server-fallback.ts | 252 +------ src/core/chatgpt-desktop/cdp-adapter.ts | 61 +- src/core/chatgpt-desktop/cdp-dom.ts | 93 +-- src/core/chatgpt-desktop/cdp-session.ts | 59 +- src/core/chatgpt-desktop/errors.ts | 25 +- src/core/chatgpt-desktop/facade.ts | 77 +- src/core/chatgpt-desktop/loopback.ts | 3 +- src/core/chatgpt-desktop/remote-threads.ts | 29 +- src/core/chatgpt-desktop/routes.ts | 39 +- src/core/codex-bridge.js | 10 +- src/core/codex/routes.ts | 6 +- src/core/codex/thread-id.js | 10 +- .../tools/chatgpt_desktop_list_hosts.tsx | 2 +- test/codex-bridge.test.js | 4 + .../route-unit/chatgpt-desktop-review.test.ts | 246 +++++++ tests/route-unit/chatgpt-desktop.test.ts | 4 +- 27 files changed, 1553 insertions(+), 2124 deletions(-) create mode 100644 tests/route-unit/chatgpt-desktop-review.test.ts diff --git a/.changeset/chatgpt-desktop-cdp.md b/.changeset/chatgpt-desktop-cdp.md index cf39e5c..86c2736 100644 --- a/.changeset/chatgpt-desktop-cdp.md +++ b/.changeset/chatgpt-desktop-cdp.md @@ -3,3 +3,5 @@ --- Scaffold ChatGPT Desktop CDP adapter and MCP/CLI tools (`chatgpt_desktop_*`). List/search keep separate `host` / `modelProvider` filters; `list_hosts` discovers hosts and providers. Codex list-threads always passes `modelProviders: []`, pages via `nextCursor`, and falls back from `useStateDbOnly` when empty. Codex send/read/wait strip Desktop `local:` ids; remote-control "thread not loaded" maps to `REMOTE_THREAD_NOT_LOADED` with host. Thread reads use `thread/read` metadata + `thread/turns/list` (never deprecated `includeTurns`). + +Keep CDP loopback-only across discovery, bound and close sessions, serialize UI operations, distinguish partial replies and uncertain sends, and preserve dynamic remote/provider filtering and ordered empty-safe history reads. diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index ab3b08c..0f816d5 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"fc47b8e753000fdd32a07395bc8afe45ab9fffca0539d2aec09b8446245d5a91"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"efbfbeb3e1f1f2ad31045541b889263c92782abe5df5c955d93401418dac3686"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"fe94b3b3a90861ae02b9a886b48d0015a82fe0b7d1678ec5658253d064226df7"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/chatgpt-desktop/remote-threads.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"fbaeefc8572b8b0eca6b7e03a687180d20ab4d1a72174a3d3cbdc5451d79ac80"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"ef7223d4be069f7e989a2c9e541f7cff510d46b3c126ceff5c907d666f87276b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"f563c98eb0a699dc9bcc787c2d6dfa59b32026cd3fd113ea399c047788c9316d"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"7de9950e8f436024ef8bef47c406f7c4f720bd395de466a2593cb8fc6bdaa74b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b401a79c4f972b075d61602627f53472cdea0ebbb44e0995c49bbf0bbdcbacfe"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"2d6a8f6474f457729ad16d53810bea3098ecd94ee261e33b4eff60c3c879e74f"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 1a6caff..0f0c328 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"7ec0384da75e7531f81734aeee0078b2fc8d89ad78b6521079dcbd3b67493dc9","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"3b77f5581c9ee6ec5413cd08d2d5ae895cdc7e60b9f036ed6e5206fc713c4c26","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"6a8b392ec45d4a5f70ce68fa35a285c2948c72d05671b07696b9ec9b0021cb89"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"ca5aec4741cb3ac4e7a4239859521e18994b49fc919a3a3bf59ce3a363ea9875"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"10081fcda493b2e0301f4f0e0dee8034f01705a60f895570224fbefa5fffa790"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"bf5fbf512fa80bf7d107fcef8052b66c7911961726371f9bc35ea33af0467996"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"659483af940524ef155f505a0f4235ef76ed50a849a86fa1d7834256a0588838"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5ba4f07e35239c59cff2815eadb957fb13cf682d12bb25bf192f6bd8691eb4a5"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"583279e0360f529405948a6fb33712dabaa9917bb616bd00dcc83a6b6422827c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"f9eb6f1333359c0523b2d4682a2ffac4dd79d0e60f5354b2e8d865443327d768"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"436567316d576e343963bcaff2086674e172bf42d4ff62a76e52e8b2d41897eb"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"92a886e03fffee8f5741f763deedc3d372e8c177b4fc6fea8fd37db3f1f13744"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"9b35df3fa9a4a1655b9cb2e2f0d3b83e796648fc8d4ab3cacfa856f78e6a2df5"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"6690338b2d0b1d1013f5d4b851ffca12e9f51fb95e791481713c658ba672e511"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"acb18dcd93dca4893d6c69f6ba598beec2440b9dabf6e7f13ddb0eda241c6aa7"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"f4843da5a5fde4728e2dfe6766be0ce29b50a45af8a9508df8fcf86dffaee651"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"78de63808c3479932dff35cab0f2a9a78e84183187eb9a783823b5193b6f76c3"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"d260ca3a9d150900cc1a2e4f3df2e8f3712714ed9be2ecd6a646eda6e7b1b8d4"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"6f49f1cce9590831953915a8f1f8ecc3e641bc5a1230a26f35937f257393bc26"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"dfaf2ea60ea7e46be61accc91b20e591125618c83a1910ea20ed72a75322f9d8"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4d5f799e587d8d4be6e7bacb9209816c7756605f75a0595dc3d3052f04048624"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"a3d97e4e62b693a19828b5dea466505fcf2a08df705b9c302abde0990344c1d4"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"521496fdfaff13cb55f4decb9e78ebaa1d2e35e7bfcc38cc887375b200724961"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"c473cd9f3954480e3280ad5ed8eef7b135571c94e0ff0a3b7f825348406b762c"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"6c5b87b456c7a4cece6fa61ed3b4f4b0bee21e356db7b643b2838ccefbdfa4a6"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"b671db62ea723a21e11f69ba4b857e271573db22dd61aeb1d152b989824df5cb"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22816,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"9eeed4180d7a7c4261baf98b4b5ae66d8b9fa89558f30f0135cb57ec39d51504"},{"bytes":1521462,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"fc47b8e753000fdd32a07395bc8afe45ab9fffca0539d2aec09b8446245d5a91"},{"bytes":2385935,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"efbfbeb3e1f1f2ad31045541b889263c92782abe5df5c955d93401418dac3686"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1442545,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"fe94b3b3a90861ae02b9a886b48d0015a82fe0b7d1678ec5658253d064226df7"},{"bytes":3269060,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"fbaeefc8572b8b0eca6b7e03a687180d20ab4d1a72174a3d3cbdc5451d79ac80"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298440,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"633027625ae8bb836f35f40911695bf4b6e5d38a8c7159cdb0041690da91e88d"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"c03763e77aa906b90f360d4a607419d90c10362bd377c16bc04688eecf36f435","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"2801fc8bb76c233d7ef0a7ba2d105ee662549c7d3def3caf521129751449e790","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"bb9cf27257103b6a3ecf613b483a24a2a4ec192208a103f731368bbc31e6a5bc","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"87d63f5b0bada3621036657c544f9d5345619add70040b4ec201760541ffae7a"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"plugin/artifact/.agents/plugins/marketplace.json","sha256":"fb3366f72f193629c7d4209091e97108a3c263474f060f344e2cba22bf0fe23b"},{"executable":false,"path":"plugin/artifact/.claude-plugin/marketplace.json","sha256":"581b674cc9c0d0770c57d90c8bf9e8cbe5fd61431dc668cf37ef2e2f41f1f101"},{"executable":false,"path":"plugin/artifact/.claude-plugin/plugin.json","sha256":"82898ac16c42a9765c7b4db5614ed4700774060612d76a8bc7bf521772f32f46"},{"executable":false,"path":"plugin/artifact/.codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"executable":false,"path":"plugin/artifact/.codex-plugin/plugin.json","sha256":"91f82ce1f58fe0ac6fdd4997a13ede64e74a07a830acaf90e84148e4e3facb62"},{"executable":false,"path":"plugin/artifact/.cursor-plugin/marketplace.json","sha256":"5a3e70383773b9588887a10327b3912a99dad6ce4776ecbb87ebe9e18ad27e34"},{"executable":false,"path":"plugin/artifact/.cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"executable":false,"path":"plugin/artifact/.cursor-plugin/plugin.json","sha256":"3cc7d4307cbfde391f087069a00dea2585052ade8476c926ff16a91f44eff447"},{"executable":false,"path":"plugin/artifact/.mcp.json","sha256":"2539f66ffcb1c98a365f078c63122a1c25b7c7625f91314467843bde7628907b"},{"executable":false,"path":"plugin/artifact/agent-bundle.compile-evidence.json","sha256":"06b645955133c9ef447527df64ab81a7fbd044714bf5b757e3842fe1ad836c99"},{"executable":false,"path":"plugin/artifact/agent-bundle.manifest.json","sha256":"11ea7fd533a82996beae587b0578bed15e6ed14007166d85ddb0f6948a17f250"},{"executable":false,"path":"plugin/artifact/INSTALL.md","sha256":"05d6646fbe837407227fe482ca454224ff9fad86561b6366b0215b1148e7bc36"},{"executable":false,"path":"plugin/artifact/install.mjs","sha256":"2beddd1bd9ef0b575e5dd6d8f0dd83c734ce296b4b941bb0bb3098fc75ef15d1"},{"executable":false,"path":"plugin/artifact/mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"executable":false,"path":"plugin/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"25c576a53c0b554136b1712f801d20837b7f14173acaf2bfe816da556ac64f18"},{"executable":false,"path":"plugin/artifact/mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"3832b6ed0cd8e2a96df26864407f99cb82f5a791ddb1984136897eb20d8afccb"},{"executable":false,"path":"plugin/artifact/plugin.json","sha256":"a6b67f279bc827ea40117d3d0a48e64a1a14774173ade8a3775e1aa30812ed2e"},{"executable":false,"path":"plugin/artifact/skills/talk-to-grok-bot/SKILL.md","sha256":"ed7cca3e35080a8eb86b57e5b913172e26bccf25f45443255fcb2aa524abf91b"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"5cdd948062f0ba15af16917870c74d77259ed97af008d15bce95095e246129c9"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"659483af940524ef155f505a0f4235ef76ed50a849a86fa1d7834256a0588838"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5ba4f07e35239c59cff2815eadb957fb13cf682d12bb25bf192f6bd8691eb4a5"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"14cd66c5b689ff9f587f7ca4eff32320903c7fb911f4306724141ceef7d9041a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"429ccecd068b34f7fb230a14f0b6ca662d2e5d61b6edc8d3fdfd54d91617d4ed"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"e72142dd6a4dfe49f103ca660f0dfe8a0a0df8759a8707d0a62cbad2b6df5c2c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"a33860336ea2c336d2f0a17168502f8dad37bce7de671ebc826a1652fd69c196"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"00a6c3f836e13e86bc8ffdcc621e3e360fe451e57d3c4af31f40a50bbd5ac65d"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"1bd8d2a4dba6d848331d5656c7e00649992435bcbd1f87903adc0a26179ebadf"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"143f138d886b4f20fa65bd61d01d01df19103cc386fffd3e331176e721a307e9"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"d260ca3a9d150900cc1a2e4f3df2e8f3712714ed9be2ecd6a646eda6e7b1b8d4"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"f2e1131e6f973fe8efb277022e77731196fbdaa226bede64ecfeae9eb0d0de2c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"f4d5e0377cdb7297754d3220c1935fc65bfb5f605b3bc0f15f5ff328f0ce3b63"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"5d7b69f5b0502039a086f1903951d735b02fb57107214b0f4d4d6abc349f352f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"521496fdfaff13cb55f4decb9e78ebaa1d2e35e7bfcc38cc887375b200724961"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"3de602b6e5ac42cfe0f2fe65a9c060a3d54bf8891eb8579538d412d7cfdb6c07"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"047c6bd900de50ae5ef8b1ac9391fdcaee5068af59f16cf1c2c3e23d0aea5385"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"dbdd7cddefe3a1844e5c5913212f69875422d43b199cda692a15a6f76a74f7d5"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"b671db62ea723a21e11f69ba4b857e271573db22dd61aeb1d152b989824df5cb"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22276,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"55f52504ebcd3b4dc458ee4bbc99acb82aa3126f297a1101098130ad502cabb7"},{"bytes":1517603,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"ef7223d4be069f7e989a2c9e541f7cff510d46b3c126ceff5c907d666f87276b"},{"bytes":2382022,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"f563c98eb0a699dc9bcc787c2d6dfa59b32026cd3fd113ea399c047788c9316d"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1438250,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"7de9950e8f436024ef8bef47c406f7c4f720bd395de466a2593cb8fc6bdaa74b"},{"bytes":3264765,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b401a79c4f972b075d61602627f53472cdea0ebbb44e0995c49bbf0bbdcbacfe"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298594,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"2d6a8f6474f457729ad16d53810bea3098ecd94ee261e33b4eff60c3c879e74f"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"d0a620dd430c8ea389c97594c33d46a52acc58baa1bb85923ade99766c58b9da","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index cb49174..b655a49 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -8616,7 +8616,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.', + description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, @@ -8845,7 +8845,7 @@ var __webpack_modules__ = { type: 'object' }, render: { - maxElapsedMs: 180000 + maxElapsedMs: 660000 } }; const inputSchema = zod__rspack_import_2.Ikc({ @@ -11321,46 +11321,7 @@ var __webpack_modules__ = { modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } - const MODEL_PROVIDER_LIST_METHODS = [ - 'modelProvider/list', - 'model/providers/list', - 'models/providers/list', - 'account/modelProviders/list', - 'config/modelProviders/list', - 'provider/list' - ]; - const REMOTE_ENVIRONMENT_LIST_METHODS = [ - 'remoteEnvironment/list', - 'remote/environments/list', - 'environment/list', - 'remoteControl/hosts/list', - 'remote/hosts/list', - 'hosts/list' - ]; async function discoverModelProviders() { - const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); - try { - for (const method of MODEL_PROVIDER_LIST_METHODS){ - try { - const result = await client.request(method, {}); - const providers = normalizeNamedList(result, [ - 'id', - 'name', - 'provider', - 'modelProvider', - 'slug' - ]); - if (providers.length > 0) { - return { - providers, - source: `app-server:${method}` - }; - } - } catch {} - } - } finally{ - client.close(); - } const providers = new Set(); let cursor; for(let page = 0; page < 20; page++){ @@ -11384,113 +11345,6 @@ var __webpack_modules__ = { source: 'thread/list-distinct' }; } - async function discoverRemoteEnvironments() { - const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); - try { - for (const method of REMOTE_ENVIRONMENT_LIST_METHODS){ - try { - const result = await client.request(method, {}); - const hosts = normalizeHostEntries(result); - if (hosts.length > 0) { - return { - hosts, - source: `app-server:${method}` - }; - } - } catch {} - } - } finally{ - client.close(); - } - return { - hosts: [], - source: null - }; - } - function normalizeNamedList(result, idKeys) { - const raw = listPayload(result); - const out = []; - for (const entry of raw){ - if (typeof entry === 'string' && entry) out.push(entry); - else if (entry && typeof entry === 'object') { - const row = entry; - for (const key of idKeys){ - if (typeof row[key] === 'string' && row[key]) { - out.push(String(row[key])); - break; - } - } - } - } - return [ - ...new Set(out) - ].sort(); - } - function normalizeHostEntries(result) { - const raw = listPayload(result); - const out = []; - for (const entry of raw){ - if (typeof entry === 'string' && entry) { - out.push({ - hostId: entry, - hostName: null - }); - continue; - } - if (!entry || typeof entry !== 'object') continue; - const row = entry; - let hostId = null; - for (const key of [ - 'hostId', - 'id', - 'uuid', - 'environmentId', - 'envId' - ]){ - if (typeof row[key] === 'string' && row[key]) { - hostId = String(row[key]); - break; - } - } - if (!hostId) continue; - let hostName = null; - for (const key of [ - 'hostName', - 'name', - 'displayName', - 'envName', - 'label', - 'title' - ]){ - if (typeof row[key] === 'string' && row[key]) { - hostName = String(row[key]); - break; - } - } - out.push({ - hostId, - hostName - }); - } - return out; - } - function listPayload(result) { - if (Array.isArray(result)) return result; - if (!result || typeof result !== 'object') return []; - const record = result; - for (const key of [ - 'data', - 'providers', - 'modelProviders', - 'hosts', - 'environments', - 'remoteEnvironments', - 'items' - ]){ - if (Array.isArray(record[key])) return record[key]; - } - return []; - } async function appServerReadThread({ threadId, limit = 100, full = false }) { const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); @@ -11615,85 +11469,46 @@ var __webpack_modules__ = { async function listTurnsFull(client, threadId, { limit, full }) { const collected = []; let cursor; - try { - for(let page = 0; page < 40; page++){ - const result = await client.request('thread/turns/list', { + let itemsView = true; + let method = 'thread/turns/list'; + const seen = new Set(); + while(collected.length < limit){ + let result; + try { + result = await client.request(method, { threadId, - limit: 100, - itemsView: 'full', - ...cursor ? { + limit: Math.min(100, limit - collected.length), + sortDirection: full ? 'asc' : 'desc', + ...method === 'thread/turns/list' && itemsView ? { + itemsView: 'full' + } : {}, + ...cursor !== undefined ? { cursor } : {} }); - if (!Array.isArray(result.data)) { - throw new Error(`thread/turns/list missing data array for ${threadId}`); + } catch (error) { + const code = error?.rpc?.code; + if (collected.length === 0 && code === -32602 && itemsView) { + itemsView = false; + continue; } - collected.push(...result.data); - if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; - cursor = result.nextCursor; - if (!full && collected.length >= limit) break; - } - } catch (error) { - if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); - if (collected.length === 0) { - return listTurnsFallback(client, threadId, { - limit, - full - }); - } - throw error; - } - if (collected.length === 0) { - return listTurnsFallback(client, threadId, { - limit, - full - }); - } - return sliceTurns(normalizeTurns(collected), { - limit, - full - }); - } - async function listTurnsFallback(client, threadId, { limit, full }) { - for (const method of [ - 'thread/turns/list', - 'thread/items/list' - ]){ - try { - const collected = []; - let cursor; - for(let page = 0; page < 40; page++){ - const params = { - threadId, - limit: 100, - ...cursor ? { - cursor - } : {} - }; - if (method === 'thread/turns/list') params.itemsView = 'full'; - const result = await client.request(method, params); - if (!Array.isArray(result.data)) break; - collected.push(...result.data); - if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; - cursor = result.nextCursor; - if (!full && collected.length >= limit) break; - } - if (collected.length > 0) { - return sliceTurns(normalizeTurns(collected), { - limit, - full - }); + if (collected.length === 0 && code === -32601 && method === 'thread/turns/list') { + method = 'thread/items/list'; + continue; } - } catch (error) { - if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + throw maybeRemoteThreadError(error, threadId); } + if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); + collected.push(...result.data); + if (result.nextCursor == null) break; + if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { + throw new Error(`${method} returned an invalid or repeated cursor`); + } + seen.add(result.nextCursor); + cursor = result.nextCursor; } - throw new Error(`app-server has no turn history for thread ${threadId}`); - } - function sliceTurns(turns, { limit, full }) { - if (limit <= 0) return turns; - if (full) return turns.slice(0, limit); - return turns.slice(-limit); + const turns = normalizeTurns(collected.slice(0, limit)); + return full ? turns : turns.reverse(); } function normalizeTurns(raw) { const turns = []; @@ -11816,7 +11631,6 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, - OP: ()=>discoverRemoteEnvironments, X: ()=>discoverModelProviders, aI: ()=>appServerSearchThreads, dM: ()=>appServerStatusProbe @@ -11834,6 +11648,7 @@ var __webpack_modules__ = { #version = null; #pageSessionId = null; #mainTargetId = null; + #submittedTurn = null; async connect({ port }) { await this.close(); this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); @@ -11890,25 +11705,40 @@ var __webpack_modules__ = { await (0, _cdp_dom_js__rspack_import_2.s0)(this.#requireSession(), sessionId, { project }); - await delay(300); + await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { + timeoutMs: openTimeoutMs, + threadId: 'new' + }); const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { limit: 20 }); const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); if (temp) temporaryThreadId = temp.threadId; } + const before = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); let conversationId; if (startedNew || threadId && (0, _thread_ids_js__rspack_import_3.vr)(threadId)) { const resolveMs = Math.min(openTimeoutMs, 60000); - conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { - timeoutMs: resolveMs - }); + try { + conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { + timeoutMs: resolveMs + }); + } catch (error) { + throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), { + delivery: 'unknown', + reason: 'conversation-id-unresolved' + }); + } } const durable = (0, _cdp_dom_js__rspack_import_2.X8)(conversationId, threadId); if (!durable) { throw new Error('ChatGPT Desktop send accepted but no durable conversation id was available; ' + 'refusing to return a local:client-new-thread:* id as threadId'); } + this.#submittedTurn = { + threadId: durable, + turnKey: before.lastTurnKey + }; return { threadId: durable, temporaryThreadId, @@ -11922,17 +11752,17 @@ var __webpack_modules__ = { }; } async waitForReply({ threadId, timeoutMs = 120000 }) { + const deadline = Date.now() + timeoutMs; const sessionId = await this.#ensurePageSession(); + const expectedId = threadId && threadId !== 'new' ? (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? undefined : this.#submittedTurn ? (0, _thread_ids_js__rspack_import_3.nn)(this.#submittedTurn.threadId) ?? undefined : undefined; if (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) && threadId !== 'new') { - try { - await this.#openAndWait(sessionId, threadId, 90000); - } catch {} + await this.#openAndWait(sessionId, threadId, Math.min(timeoutMs, 90000)); } - const baseline = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); try { const done = await (0, _cdp_dom_js__rspack_import_2.FG)(this.#requireSession(), sessionId, { - timeoutMs, - baselineFinalCount: baseline.finalAssistantCount + timeoutMs: Math.max(0, deadline - Date.now()), + expectedConversationId: expectedId, + baselineTurnKey: this.#submittedTurn && (!threadId || (0, _thread_ids_js__rspack_import_3.BS)(threadId) === this.#submittedTurn.threadId) ? this.#submittedTurn.turnKey : undefined }); const durable = (0, _cdp_dom_js__rspack_import_2.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_3.BS)(done.conversationId) : null); if (!durable) { @@ -11947,26 +11777,13 @@ var __webpack_modules__ = { delivery: 'replied' }; } catch (error) { - const last = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); - const durable = (0, _cdp_dom_js__rspack_import_2.X8)(last.conversationId, threadId); - if (last.reply && durable) { - return { - threadId: durable, - conversationId: last.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, - reply: last.reply, - backend: 'cdp', - experimental: false, - delivery: 'replied' - }; - } + if (!(error instanceof _cdp_dom_js__rspack_import_2.aw)) throw error; return { - threadId: durable ?? (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) ? threadId : 'unknown'), - conversationId: last.conversationId || undefined, - reply: last.reply, + threadId: threadId ?? 'unknown', + reply: '', backend: 'cdp', experimental: false, - delivery: last.reply ? 'replied' : 'timeout', - ...error instanceof Error ? {} : {} + delivery: 'timeout' }; } } @@ -12023,7 +11840,8 @@ var __webpack_modules__ = { async #openAndWait(sessionId, threadId, openTimeoutMs) { await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { - timeoutMs: openTimeoutMs + timeoutMs: openTimeoutMs, + threadId }); } async #attachMainWindow() { @@ -12054,9 +11872,6 @@ var __webpack_modules__ = { return this.#session; } } - function delay(ms) { - return new Promise((resolve)=>setTimeout(resolve, ms)); - } __webpack_require__.d(__webpack_exports__, { a: ()=>CdpChatGptDesktopAdapter }); @@ -12231,6 +12046,7 @@ var __webpack_modules__ = { preferred.click(); return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; } + return { ok: false, error: 'project-not-found' }; } const buttons = Array.from(document.querySelectorAll('button')); const fallback = buttons.find((btn) => (btn.textContent || '').trim() === 'New chat'); @@ -12253,6 +12069,8 @@ var __webpack_modules__ = { const FOCUS_COMPOSER_EXPRESSION = `(() => { const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); if (!composer) return { ok: false, error: 'composer-not-found' }; + if ((composer.textContent || '').trim()) return { ok: false, error: 'composer-has-draft' }; + if (document.querySelector(${JSON.stringify(STOP_BUTTON_SELECTOR)})) return { ok: false, error: 'reply-in-progress' }; composer.focus(); return { ok: true }; })()`; @@ -12280,6 +12098,7 @@ var __webpack_modules__ = { conversationId, reply, lastTurnKey, + finalTurnKey: lastFinal?.closest(${JSON.stringify(SELECTORS.turn)})?.getAttribute(${JSON.stringify(ATTR.turnKey)}) || '', }; })()`; const CONVERSATION_ID_EXPRESSION = `(() => { @@ -12364,13 +12183,23 @@ var __webpack_modules__ = { throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); } } - async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS } = {}) { + async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS, threadId } = {}) { const deadline = Date.now() + timeoutMs; while(Date.now() < deadline){ const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { sessionId }); - if (gone) return; + if (gone) { + const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; + if (!threadId) return; + if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + const rows = await listThreadsFromDom(session, sessionId, { + limit: 200 + }); + const selected = rows.find((row)=>row.selected); + if (!current && (!selected || (0, _codex_thread_id_js__rspack_import_0.vr)(selected.threadId))) return; + } else if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; + } await delay(250); } throw new Error(`ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); @@ -12391,7 +12220,7 @@ var __webpack_modules__ = { sessionId }); if (!focused?.ok) { - throw new Error('ChatGPT Desktop composer not found ([data-codex-composer=true])'); + throw new Error(`ChatGPT Desktop composer unavailable: ${focused?.error || 'not found'}`); } } async function submitComposerWithEnter(session, sessionId) { @@ -12408,12 +12237,6 @@ var __webpack_modules__ = { }, { sessionId }); - await session.send('Input.dispatchKeyEvent', { - type: 'char', - ...base - }, { - sessionId - }); await session.send('Input.dispatchKeyEvent', { type: 'keyUp', ...base @@ -12421,17 +12244,6 @@ var __webpack_modules__ = { sessionId }); } - async function submitComposerWithButton(session, sessionId) { - const result = await session.evaluate(`(() => { - const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); - if (!btn || btn.disabled) return { ok: false }; - btn.click(); - return { ok: true }; - })()`, { - sessionId - }); - return Boolean(result?.ok); - } async function sendMessageInDom(session, sessionId, text) { await focusComposer(session, sessionId); await session.send('Input.insertText', { @@ -12439,22 +12251,28 @@ var __webpack_modules__ = { }, { sessionId }); - await submitComposerWithEnter(session, sessionId); - const sendStillVisible = await session.evaluate(`(() => { - const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); - return Boolean(btn && !btn.disabled); - })()`, { - sessionId - }); - if (sendStillVisible) { - const clicked = await submitComposerWithButton(session, sessionId); - if (clicked) return { - sentVia: 'button' - }; + try { + await submitComposerWithEnter(session, sessionId); + const deadline = Date.now() + 3000; + while(Date.now() < deadline){ + const cleared = await session.evaluate(`(() => { + const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + return Boolean(composer && !(composer.textContent || '').trim()); + })()`, { + sessionId + }); + if (cleared) return { + sentVia: 'enter' + }; + await delay(100); + } + throw new Error('Desktop composer did not acknowledge submission'); + } catch (error) { + throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), { + delivery: 'unknown', + reason: 'submission-unconfirmed' + }); } - return { - sentVia: 'enter' - }; } async function readReplyState(session, sessionId) { const state = await session.evaluate(REPLY_STATE_EXPRESSION, { @@ -12465,7 +12283,8 @@ var __webpack_modules__ = { finalAssistantCount: Number(state?.finalAssistantCount ?? 0), conversationId: String(state?.conversationId ?? ''), reply: String(state?.reply ?? ''), - lastTurnKey: String(state?.lastTurnKey ?? '') + lastTurnKey: String(state?.lastTurnKey ?? ''), + finalTurnKey: String(state?.finalTurnKey ?? '') }; } async function readConversationIdFromDom(session, sessionId) { @@ -12494,14 +12313,21 @@ var __webpack_modules__ = { } return null; } - async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0 } = {}) { + class ReplyTimeoutError extends Error { + } + async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0, expectedConversationId, baselineTurnKey } = {}) { const deadline = Date.now() + timeoutMs; let sawStop = false; const started = Date.now(); while(Date.now() < deadline){ const state = await readReplyState(session, sessionId); if (state.stopVisible) sawStop = true; - const hasNewFinal = state.finalAssistantCount > baselineFinalCount && Boolean(state.reply); + expectedConversationId ??= state.conversationId || undefined; + if (expectedConversationId && state.conversationId && durableThreadKey(state.conversationId) !== durableThreadKey(expectedConversationId)) { + throw new Error('ChatGPT Desktop selected conversation changed while waiting'); + } + const latestIsFinal = Boolean(state.finalTurnKey) && state.finalTurnKey === state.lastTurnKey; + const hasNewFinal = (state.finalAssistantCount > baselineFinalCount || sawStop) && Boolean(state.reply) && latestIsFinal && (!baselineTurnKey || state.lastTurnKey !== baselineTurnKey); if (!state.stopVisible && hasNewFinal && (sawStop || Date.now() - started > 1500)) { return { reply: state.reply, @@ -12510,14 +12336,7 @@ var __webpack_modules__ = { } await delay(200); } - const last = await readReplyState(session, sessionId); - if (!last.stopVisible && last.finalAssistantCount > baselineFinalCount && last.reply) { - return { - reply: last.reply, - conversationId: last.conversationId - }; - } - throw new Error(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); + throw new ReplyTimeoutError(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); } function normalizeTurn(raw) { const role = raw.role === 'user' || raw.role === 'status' || raw.role === 'assistant' ? raw.role : raw.assistantText ? 'assistant' : raw.userText ? 'user' : 'assistant'; @@ -12594,6 +12413,7 @@ var __webpack_modules__ = { X8: ()=>resolveDurableThreadId, YX: ()=>readReplyState, Zx: ()=>waitForLoadingTaskGone, + aw: ()=>ReplyTimeoutError, lh: ()=>sendMessageInDom, s0: ()=>startNewChatInDom, z9: ()=>waitForConversationId @@ -12624,7 +12444,11 @@ var __webpack_modules__ = { let response; try { response = await fetch(`${base}/json/version`, { - signal + signal: signal ? AbortSignal.any([ + signal, + AbortSignal.timeout(5000) + ]) : AbortSignal.timeout(5000), + redirect: 'error' }); } catch (error) { throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/version: ` + (error instanceof Error ? error.message : String(error))); @@ -12632,14 +12456,22 @@ var __webpack_modules__ = { if (!response.ok) { throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP /json/version returned HTTP ${response.status}`); } - return await response.json(); + const version = await response.json(); + if (typeof version.webSocketDebuggerUrl === 'string') { + (0, _loopback_js__rspack_import_1.jv)(version.webSocketDebuggerUrl); + } + return version; } static async fetchJsonList(port, { signal } = {}) { const base = (0, _loopback_js__rspack_import_1.NJ)(port); let response; try { response = await fetch(`${base}/json/list`, { - signal + signal: signal ? AbortSignal.any([ + signal, + AbortSignal.timeout(5000) + ]) : AbortSignal.timeout(5000), + redirect: 'error' }); } catch (error) { throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/list: ` + (error instanceof Error ? error.message : String(error))); @@ -12662,35 +12494,43 @@ var __webpack_modules__ = { throw new _errors_js__rspack_import_0.sO('CDP /json/version omitted webSocketDebuggerUrl'); } const url = (0, _loopback_js__rspack_import_1.jv)(rawUrl); - const parsed = new URL(url); - (0, _loopback_js__rspack_import_1.tb)(parsed.hostname); + signal?.throwIfAborted(); await new Promise((resolve, reject)=>{ const ws = new WebSocket(url); this.#ws = ws; + const cleanup = ()=>{ + clearTimeout(timer); + signal?.removeEventListener('abort', onAbort); + }; const onAbort = ()=>{ + cleanup(); ws.close(); - reject(new Error('CDP connect aborted')); + reject(new _errors_js__rspack_import_0.sO('CDP connect aborted or timed out')); }; + const timer = setTimeout(onAbort, 5000); signal?.addEventListener('abort', onAbort, { once: true }); ws.addEventListener('open', ()=>{ - signal?.removeEventListener('abort', onAbort); + cleanup(); resolve(); }, { once: true }); ws.addEventListener('error', ()=>{ - signal?.removeEventListener('abort', onAbort); + cleanup(); reject(new _errors_js__rspack_import_0.sO(`CDP WebSocket failed for ${url}`)); }, { once: true }); ws.addEventListener('message', (event)=>this.#onMessage(event.data)); ws.addEventListener('close', ()=>{ + cleanup(); + reject(new _errors_js__rspack_import_0.sO('CDP WebSocket closed before connecting')); this.#closed = true; for (const [, pending] of this.#pending){ - pending.reject(new Error('CDP WebSocket closed')); + clearTimeout(pending.timer); + pending.reject(new _errors_js__rspack_import_0.sO('CDP WebSocket closed')); } this.#pending.clear(); }); @@ -12710,11 +12550,22 @@ var __webpack_modules__ = { if (params !== undefined) payload.params = params; if (sessionId !== undefined) payload.sessionId = sessionId; return await new Promise((resolve, reject)=>{ + const timer = setTimeout(()=>{ + this.#pending.delete(id); + reject(new _errors_js__rspack_import_0.sO(`CDP ${method} timed out`)); + }, 10000); this.#pending.set(id, { + timer, resolve: (value)=>resolve(value), reject }); - this.#ws.send(JSON.stringify(payload)); + try { + this.#ws.send(JSON.stringify(payload)); + } catch (error) { + clearTimeout(timer); + this.#pending.delete(id); + reject(error); + } }); } async evaluate(expression, { sessionId, awaitPromise = true } = {}) { @@ -12733,6 +12584,11 @@ var __webpack_modules__ = { } close() { this.#closed = true; + for (const pending of this.#pending.values()){ + clearTimeout(pending.timer); + pending.reject(new _errors_js__rspack_import_0.sO('CDP session closed')); + } + this.#pending.clear(); this.#ws?.close(); this.#ws = null; } @@ -12743,10 +12599,11 @@ var __webpack_modules__ = { } catch { return; } - if (typeof message.id !== 'number') return; + if (!message || typeof message !== 'object' || typeof message.id !== 'number') return; const pending = this.#pending.get(message.id); if (!pending) return; this.#pending.delete(message.id); + clearTimeout(pending.timer); if (message.error) { pending.reject(new Error(message.error.message || 'CDP error')); return; @@ -12787,15 +12644,9 @@ var __webpack_modules__ = { this.name = 'CdpUnreachableError'; } } - class RemoteThreadNotLoadedError1 extends _codex_remote_control_js__rspack_import_0.Rg { - constructor(threadId, hostId = null, hostName = null){ - super(threadId, hostId, hostName); - this.name = 'RemoteThreadNotLoadedError'; - } - } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, - Rg: ()=>RemoteThreadNotLoadedError1, + Rg: ()=>_codex_remote_control_js__rspack_import_0.Rg, c$: ()=>CdpHostRejectedError, sO: ()=>CdpUnreachableError }); @@ -12814,8 +12665,7 @@ var __webpack_modules__ = { statusProbe: _app_server_fallback_js__rspack_import_1.dM, listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, listHosts: _remote_threads_js__rspack_import_4.Kl, - discoverModelProviders: _app_server_fallback_js__rspack_import_1.X, - discoverRemoteEnvironments: _app_server_fallback_js__rspack_import_1.OP + discoverModelProviders: _app_server_fallback_js__rspack_import_1.X }; class ChatGptDesktopFacade { #cdp; @@ -12871,19 +12721,25 @@ var __webpack_modules__ = { cdpError = error; } } + const remotes = this.#listRemotes(); let base = null; if (appList && cdpList) base = mergeThreadLists(appList, cdpList); else if (appList) base = appList; else if (cdpList) base = cdpList; + else if (remotes.length) base = { + backend: 'app-server', + limit, + threads: [] + }; else if (cdpError) throw cdpError; else if (appError) throw appError; else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); return finalizeThreadList(base, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, - remotes: this.#listRemotes() + remotes }); } async listHosts() { @@ -12924,30 +12780,7 @@ var __webpack_modules__ = { }); } } - let hostsSource = 'remote-thread-summaries-v3+local'; - try { - const discoverEnvs = this.#fallbacks.discoverRemoteEnvironments ?? _app_server_fallback_js__rspack_import_1.OP; - const appHosts = await discoverEnvs(); - if (appHosts.source && appHosts.hosts.length > 0) { - for (const host of appHosts.hosts){ - const existing = byId.get(host.hostId); - if (existing) { - byId.set(host.hostId, { - ...existing, - hostName: existing.hostName ?? host.hostName - }); - } else { - byId.set(host.hostId, { - hostId: host.hostId, - hostName: host.hostName, - location: 'remote', - threadCount: 0 - }); - } - } - hostsSource = `${appHosts.source}+remote-thread-summaries-v3+local`; - } - } catch {} + const hostsSource = 'remote-thread-summaries-v3+local'; const remoteCounts = new Map(); for (const thread of remotes){ remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); @@ -12980,6 +12813,12 @@ var __webpack_modules__ = { ].sort(); modelProvidersSource = 'remote-summaries-distinct'; } + modelProviders = [ + ...new Set([ + ...modelProviders, + ...remotes.map((thread)=>thread.modelProvider).filter((value)=>Boolean(value)) + ]) + ].sort(); return { hosts: withCounts, hostsSource, @@ -13005,7 +12844,7 @@ var __webpack_modules__ = { const withRemotes = finalizeThreadList(base, { limit: 10000, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, remotes: this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); @@ -13017,7 +12856,7 @@ var __webpack_modules__ = { return finalizeThreadList(filtered, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: [] }); @@ -13025,19 +12864,23 @@ var __webpack_modules__ = { const cdpList = await this.#tryCdpList({ limit }); - if (!cdpList) throw appError; + const remotes = this.#listRemotes(); + if (!cdpList && !remotes.length) throw appError; const needle = options.query.trim().toLowerCase(); const filtered = { - ...cdpList, + ...cdpList ?? { + backend: 'app-server', + limit + }, query: options.query, - threads: cdpList.threads.filter((thread)=>threadMatchesQuery(thread, needle)) + threads: (cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) }; return finalizeThreadList(filtered, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, - remotes: this.#listRemotes() + remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) }); } } @@ -13065,7 +12908,7 @@ var __webpack_modules__ = { return this.#cdp.readThread({ ...options, limit, - full: full || true + full }); } } @@ -13170,12 +13013,7 @@ var __webpack_modules__ = { }); for (const thread of cdpList.threads){ if (merged.some((row)=>(0, _thread_ids_js__rspack_import_5.LV)(row.threadId, thread.threadId))) continue; - merged.push({ - ...thread, - location: thread.location ?? 'local', - hostId: thread.hostId ?? null, - hostName: thread.hostName ?? null - }); + merged.push(thread); } return { backend: appList.backend, @@ -13188,7 +13026,20 @@ var __webpack_modules__ = { }; } function finalizeThreadList(base, { limit, host = 'all', modelProvider, groupBy, remotes }) { + const remoteById = new Map(remotes.map((thread)=>[ + (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId, + thread + ])); const locals = base.threads.map((thread)=>{ + const remote = remoteById.get((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId); + if (remote && thread.location === undefined) { + return { + ...thread, + ...remote, + selected: thread.selected, + pinned: thread.pinned || remote.pinned + }; + } const location = thread.location ?? 'local'; return { ...thread, @@ -13286,9 +13137,6 @@ var __webpack_modules__ = { } function modelProviderMatches(thread, modelProvider) { if (!modelProvider) return true; - if (!thread.modelProvider) { - return thread.location === 'remote'; - } return thread.modelProvider === modelProvider; } function threadMatchesQuery(thread, needle) { @@ -13355,6 +13203,7 @@ var __webpack_modules__ = { throw new _errors_js__rspack_import_0.c$(String(raw)); } assertLoopbackHostname(url.hostname); + if (url.username || url.password || url.hash) throw new _errors_js__rspack_import_0.c$(raw); if (url.protocol !== 'ws:' && url.protocol !== 'wss:') { throw new Error(`Expected ws(s) debugger URL, got ${url.protocol}`); } @@ -13371,7 +13220,7 @@ var __webpack_modules__ = { } const raw = (env.CHATGPT_DESKTOP_CDP_PORT || '').trim(); if (!raw) return DEFAULT_CDP_PORT; - const port = Number.parseInt(raw, 10); + const port = /^\d+$/.test(raw) ? Number(raw) : NaN; if (!Number.isInteger(port) || port < 1 || port > 65535) { throw new RangeError('CHATGPT_DESKTOP_CDP_PORT must be an integer 1-65535'); } @@ -13380,37 +13229,15 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { L0: ()=>resolveCdpPort, NJ: ()=>cdpHttpBase, - jv: ()=>forceLoopbackWebSocketUrl, - tb: ()=>assertLoopbackHostname + jv: ()=>forceLoopbackWebSocketUrl }); }, "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var node_fs__rspack_import_0 = __webpack_require__("node:fs"); - var node_os__rspack_import_1 = __webpack_require__("node:os"); - var node_path__rspack_import_2 = __webpack_require__("node:path"); - var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; - function codexGlobalStatePath(env = process.env) { - const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); - return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); - } - function loadCodexGlobalState(env = process.env) { - let raw; - try { - raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); - } catch { - return null; - } - try { - const data = JSON.parse(raw); - if (!data || typeof data !== 'object' || Array.isArray(data)) return null; - return data; - } catch { - return null; - } - } function listRemoteThreadsFromState(env = process.env) { - const data = loadCodexGlobalState(env); + const data = (0, _codex_remote_control_js__rspack_import_0.IT)(env); if (!data) return []; const hostNames = collectHostNames(data); const out = []; @@ -13428,7 +13255,7 @@ var __webpack_modules__ = { pinnedIds }); if (!mapped) continue; - const bare = (0, _thread_ids_js__rspack_import_3.nn)(mapped.threadId) ?? mapped.threadId; + const bare = (0, _thread_ids_js__rspack_import_1.nn)(mapped.threadId) ?? mapped.threadId; const dedupe = `${hostId}:${bare}`; if (seen.has(dedupe)) continue; seen.add(dedupe); @@ -13438,10 +13265,10 @@ var __webpack_modules__ = { return out; } function findRemoteThread(threadId, env = process.env) { - const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; + const bare = (0, _thread_ids_js__rspack_import_1.nn)(threadId) ?? threadId; if (!bare) return null; for (const thread of listRemoteThreadsFromState(env)){ - const id = (0, _thread_ids_js__rspack_import_3.nn)(thread.threadId) ?? thread.threadId; + const id = (0, _thread_ids_js__rspack_import_1.nn)(thread.threadId) ?? thread.threadId; if (id === bare) { return { hostId: thread.hostId, @@ -13464,7 +13291,7 @@ var __webpack_modules__ = { location: 'local', threadCount: localThreadCount }); - const data = loadCodexGlobalState(env); + const data = (0, _codex_remote_control_js__rspack_import_0.IT)(env); if (data) { const hostNames = collectHostNames(data); for (const key of Object.keys(data)){ @@ -13652,7 +13479,7 @@ var __webpack_modules__ = { function mapRemoteEntry(entry, { hostId, hostName, pinnedIds }) { if (typeof entry === 'string' && entry) { return { - threadId: (0, _thread_ids_js__rspack_import_3.BS)(entry), + threadId: (0, _thread_ids_js__rspack_import_1.BS)(entry), title: entry, pinned: pinnedIds.has(entry), selected: false, @@ -13726,7 +13553,7 @@ var __webpack_modules__ = { ]) || sectionName; const pinned = pinnedIds.has(id) || row.pinned === true || sectionId === 'Pinned' || sectionName === 'Pinned'; return { - threadId: (0, _thread_ids_js__rspack_import_3.BS)(id), + threadId: (0, _thread_ids_js__rspack_import_1.BS)(id), title, pinned, selected: false, @@ -13836,7 +13663,7 @@ var __webpack_modules__ = { const sendSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), - text: zod__rspack_import_4.YjP().min(1).max(100000), + text: zod__rspack_import_4.YjP().trim().min(1).max(100000), project: zod__rspack_import_4.YjP().min(1).max(256).optional(), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); @@ -13851,19 +13678,27 @@ var __webpack_modules__ = { zod__rspack_import_4.euz(1) ]) }).catchall(zod__rspack_import_4.Pq9()); + let operationQueue = Promise.resolve(); async function withAdapter(port, run) { - const adapter = (0, _facade_js__rspack_import_2.PP)(); - const resolved = (0, _loopback_js__rspack_import_3.L0)(process.env, port); - try { - await adapter.connect({ - port: resolved - }); - } catch {} - return run(adapter); + const operation = operationQueue.then(async ()=>{ + const adapter = (0, _facade_js__rspack_import_2.PP)(); + const resolved = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + try { + try { + await adapter.connect({ + port: resolved + }); + } catch {} + return await run(adapter); + } finally{ + await adapter.close(); + } + }); + operationQueue = operation.catch(()=>{}); + return operation; } function asResult(value) { - const cleaned = Object.fromEntries(Object.entries(value).filter(([, entry])=>entry !== undefined)); - return resultSchema.parse(cleaned); + return resultSchema.parse(JSON.parse(JSON.stringify(value))); } function mapError(error) { if (error instanceof _errors_js__rspack_import_1.EH) { @@ -13981,6 +13816,7 @@ var __webpack_modules__ = { } async function sendOperation(input) { try { + input = sendSchema.parse(input); const out = await withAdapter(input.port, (adapter)=>adapter.sendMessage({ threadId: input.threadId, text: input.text, @@ -14013,7 +13849,7 @@ var __webpack_modules__ = { if (result.error) return String(result.error); if (result.reachable === true) { const backend = result.appServerFallback && typeof result.appServerFallback === 'object' ? ` cdp + app-server probe` : ''; - return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; + return result.message ? String(result.message) : `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); if (Array.isArray(result.hosts)) { @@ -14176,11 +14012,11 @@ var __webpack_modules__ = { }; const sendFields = { ...observationFields, - correlationId: id.optional(), + correlationId: bareId.optional(), envelope: zod__rspack_import_3.zMY().optional(), hop: zod__rspack_import_3.aig().int().min(0).optional(), - replyTo: id.optional(), - expectedTurnId: id.optional(), + replyTo: bareId.optional(), + expectedTurnId: bareId.optional(), whenBusy: zod__rspack_import_3.k5n([ 'reject', 'queue', @@ -14195,8 +14031,8 @@ var __webpack_modules__ = { }).strict(); const waitSchema = zod__rspack_import_3.Ikc({ ...observationFields, - turnId: id, - messageId: id.optional(), + turnId: bareId, + messageId: bareId.optional(), maxOutputBytes: zod__rspack_import_3.aig().int().min(1).max(4194304).optional() }).strict(); const watchSchema = zod__rspack_import_3.Ikc({ @@ -26141,6 +25977,7 @@ var __webpack_modules__ = { } const turns = []; let cursor; + const seen = new Set(); for(let page = 0; page < 40 && turns.length < limit; page++){ let out; try { @@ -26148,6 +25985,7 @@ var __webpack_modules__ = { threadId: bare, limit: Math.min(100, limit - turns.length), itemsView: "full", + sortDirection: "desc", ...cursor !== undefined ? { cursor } : {} @@ -26161,8 +25999,12 @@ var __webpack_modules__ = { throw new CodexProtocolError("thread/turns/list", "missing `data` array"); } for (const row of out.data)turns.push(row); - if (out.nextCursor == null || typeof out.nextCursor !== "string") break; - cursor = out.nextCursor; + cursor = out.nextCursor ?? null; + if (cursor === null) break; + if (typeof cursor !== "string" || !cursor || seen.has(cursor)) { + throw new CodexProtocolError("thread/turns/list", "invalid or repeated cursor"); + } + seen.add(cursor); } return { threadId: bare, @@ -27179,6 +27021,7 @@ var __webpack_modules__ = { return String(error); } __webpack_require__.d(__webpack_exports__, { + IT: ()=>loadCodexGlobalState, R3: ()=>mapRemoteThreadError, Rg: ()=>RemoteThreadNotLoadedError1 }); @@ -27188,7 +27031,7 @@ var __webpack_modules__ = { const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; const ID_PATTERN = /^[A-Za-z0-9_.:-]{1,128}$/; function isTemporaryDesktopThreadId(threadId) { - return typeof threadId === 'string' && threadId.startsWith(TEMP_THREAD_ID_PREFIX); + return typeof threadId === 'string' && (threadId.startsWith(TEMP_THREAD_ID_PREFIX) || threadId.startsWith('client-new-thread:')); } function normalizeCodexThreadId1(threadId) { if (typeof threadId !== 'string' || !threadId) { @@ -27203,9 +27046,6 @@ var __webpack_modules__ = { } return bare; } - function hasLocalThreadPrefix(threadId) { - return typeof threadId === 'string' && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) && !isTemporaryDesktopThreadId(threadId); - } __webpack_require__.d(__webpack_exports__, { SX: ()=>normalizeCodexThreadId1, vr: ()=>isTemporaryDesktopThreadId diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index 786f72d..c01e584 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -7024,7 +7024,7 @@ var __webpack_modules__ = { var zod__rspack_import_2 = __webpack_require__("./node_modules/zod/v4/classic/schemas.js"); var _core_chatgpt_desktop_routes_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const config = { - description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.', + description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, @@ -7253,7 +7253,7 @@ var __webpack_modules__ = { type: 'object' }, render: { - maxElapsedMs: 180000 + maxElapsedMs: 660000 } }; const inputSchema = zod__rspack_import_2.Ikc({ @@ -9729,46 +9729,7 @@ var __webpack_modules__ = { modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } - const MODEL_PROVIDER_LIST_METHODS = [ - 'modelProvider/list', - 'model/providers/list', - 'models/providers/list', - 'account/modelProviders/list', - 'config/modelProviders/list', - 'provider/list' - ]; - const REMOTE_ENVIRONMENT_LIST_METHODS = [ - 'remoteEnvironment/list', - 'remote/environments/list', - 'environment/list', - 'remoteControl/hosts/list', - 'remote/hosts/list', - 'hosts/list' - ]; async function discoverModelProviders() { - const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); - try { - for (const method of MODEL_PROVIDER_LIST_METHODS){ - try { - const result = await client.request(method, {}); - const providers = normalizeNamedList(result, [ - 'id', - 'name', - 'provider', - 'modelProvider', - 'slug' - ]); - if (providers.length > 0) { - return { - providers, - source: `app-server:${method}` - }; - } - } catch {} - } - } finally{ - client.close(); - } const providers = new Set(); let cursor; for(let page = 0; page < 20; page++){ @@ -9792,113 +9753,6 @@ var __webpack_modules__ = { source: 'thread/list-distinct' }; } - async function discoverRemoteEnvironments() { - const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); - try { - for (const method of REMOTE_ENVIRONMENT_LIST_METHODS){ - try { - const result = await client.request(method, {}); - const hosts = normalizeHostEntries(result); - if (hosts.length > 0) { - return { - hosts, - source: `app-server:${method}` - }; - } - } catch {} - } - } finally{ - client.close(); - } - return { - hosts: [], - source: null - }; - } - function normalizeNamedList(result, idKeys) { - const raw = listPayload(result); - const out = []; - for (const entry of raw){ - if (typeof entry === 'string' && entry) out.push(entry); - else if (entry && typeof entry === 'object') { - const row = entry; - for (const key of idKeys){ - if (typeof row[key] === 'string' && row[key]) { - out.push(String(row[key])); - break; - } - } - } - } - return [ - ...new Set(out) - ].sort(); - } - function normalizeHostEntries(result) { - const raw = listPayload(result); - const out = []; - for (const entry of raw){ - if (typeof entry === 'string' && entry) { - out.push({ - hostId: entry, - hostName: null - }); - continue; - } - if (!entry || typeof entry !== 'object') continue; - const row = entry; - let hostId = null; - for (const key of [ - 'hostId', - 'id', - 'uuid', - 'environmentId', - 'envId' - ]){ - if (typeof row[key] === 'string' && row[key]) { - hostId = String(row[key]); - break; - } - } - if (!hostId) continue; - let hostName = null; - for (const key of [ - 'hostName', - 'name', - 'displayName', - 'envName', - 'label', - 'title' - ]){ - if (typeof row[key] === 'string' && row[key]) { - hostName = String(row[key]); - break; - } - } - out.push({ - hostId, - hostName - }); - } - return out; - } - function listPayload(result) { - if (Array.isArray(result)) return result; - if (!result || typeof result !== 'object') return []; - const record = result; - for (const key of [ - 'data', - 'providers', - 'modelProviders', - 'hosts', - 'environments', - 'remoteEnvironments', - 'items' - ]){ - if (Array.isArray(record[key])) return record[key]; - } - return []; - } async function appServerReadThread({ threadId, limit = 100, full = false }) { const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); @@ -10023,85 +9877,46 @@ var __webpack_modules__ = { async function listTurnsFull(client, threadId, { limit, full }) { const collected = []; let cursor; - try { - for(let page = 0; page < 40; page++){ - const result = await client.request('thread/turns/list', { + let itemsView = true; + let method = 'thread/turns/list'; + const seen = new Set(); + while(collected.length < limit){ + let result; + try { + result = await client.request(method, { threadId, - limit: 100, - itemsView: 'full', - ...cursor ? { + limit: Math.min(100, limit - collected.length), + sortDirection: full ? 'asc' : 'desc', + ...method === 'thread/turns/list' && itemsView ? { + itemsView: 'full' + } : {}, + ...cursor !== undefined ? { cursor } : {} }); - if (!Array.isArray(result.data)) { - throw new Error(`thread/turns/list missing data array for ${threadId}`); + } catch (error) { + const code = error?.rpc?.code; + if (collected.length === 0 && code === -32602 && itemsView) { + itemsView = false; + continue; } - collected.push(...result.data); - if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; - cursor = result.nextCursor; - if (!full && collected.length >= limit) break; - } - } catch (error) { - if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); - if (collected.length === 0) { - return listTurnsFallback(client, threadId, { - limit, - full - }); - } - throw error; - } - if (collected.length === 0) { - return listTurnsFallback(client, threadId, { - limit, - full - }); - } - return sliceTurns(normalizeTurns(collected), { - limit, - full - }); - } - async function listTurnsFallback(client, threadId, { limit, full }) { - for (const method of [ - 'thread/turns/list', - 'thread/items/list' - ]){ - try { - const collected = []; - let cursor; - for(let page = 0; page < 40; page++){ - const params = { - threadId, - limit: 100, - ...cursor ? { - cursor - } : {} - }; - if (method === 'thread/turns/list') params.itemsView = 'full'; - const result = await client.request(method, params); - if (!Array.isArray(result.data)) break; - collected.push(...result.data); - if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; - cursor = result.nextCursor; - if (!full && collected.length >= limit) break; - } - if (collected.length > 0) { - return sliceTurns(normalizeTurns(collected), { - limit, - full - }); + if (collected.length === 0 && code === -32601 && method === 'thread/turns/list') { + method = 'thread/items/list'; + continue; } - } catch (error) { - if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + throw maybeRemoteThreadError(error, threadId); } + if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); + collected.push(...result.data); + if (result.nextCursor == null) break; + if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { + throw new Error(`${method} returned an invalid or repeated cursor`); + } + seen.add(result.nextCursor); + cursor = result.nextCursor; } - throw new Error(`app-server has no turn history for thread ${threadId}`); - } - function sliceTurns(turns, { limit, full }) { - if (limit <= 0) return turns; - if (full) return turns.slice(0, limit); - return turns.slice(-limit); + const turns = normalizeTurns(collected.slice(0, limit)); + return full ? turns : turns.reverse(); } function normalizeTurns(raw) { const turns = []; @@ -10224,7 +10039,6 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, - OP: ()=>discoverRemoteEnvironments, X: ()=>discoverModelProviders, aI: ()=>appServerSearchThreads, dM: ()=>appServerStatusProbe @@ -10242,6 +10056,7 @@ var __webpack_modules__ = { #version = null; #pageSessionId = null; #mainTargetId = null; + #submittedTurn = null; async connect({ port }) { await this.close(); this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); @@ -10298,25 +10113,40 @@ var __webpack_modules__ = { await (0, _cdp_dom_js__rspack_import_2.s0)(this.#requireSession(), sessionId, { project }); - await delay(300); + await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { + timeoutMs: openTimeoutMs, + threadId: 'new' + }); const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { limit: 20 }); const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); if (temp) temporaryThreadId = temp.threadId; } + const before = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); let conversationId; if (startedNew || threadId && (0, _thread_ids_js__rspack_import_3.vr)(threadId)) { const resolveMs = Math.min(openTimeoutMs, 60000); - conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { - timeoutMs: resolveMs - }); + try { + conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { + timeoutMs: resolveMs + }); + } catch (error) { + throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), { + delivery: 'unknown', + reason: 'conversation-id-unresolved' + }); + } } const durable = (0, _cdp_dom_js__rspack_import_2.X8)(conversationId, threadId); if (!durable) { throw new Error('ChatGPT Desktop send accepted but no durable conversation id was available; ' + 'refusing to return a local:client-new-thread:* id as threadId'); } + this.#submittedTurn = { + threadId: durable, + turnKey: before.lastTurnKey + }; return { threadId: durable, temporaryThreadId, @@ -10330,17 +10160,17 @@ var __webpack_modules__ = { }; } async waitForReply({ threadId, timeoutMs = 120000 }) { + const deadline = Date.now() + timeoutMs; const sessionId = await this.#ensurePageSession(); + const expectedId = threadId && threadId !== 'new' ? (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? undefined : this.#submittedTurn ? (0, _thread_ids_js__rspack_import_3.nn)(this.#submittedTurn.threadId) ?? undefined : undefined; if (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) && threadId !== 'new') { - try { - await this.#openAndWait(sessionId, threadId, 90000); - } catch {} + await this.#openAndWait(sessionId, threadId, Math.min(timeoutMs, 90000)); } - const baseline = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); try { const done = await (0, _cdp_dom_js__rspack_import_2.FG)(this.#requireSession(), sessionId, { - timeoutMs, - baselineFinalCount: baseline.finalAssistantCount + timeoutMs: Math.max(0, deadline - Date.now()), + expectedConversationId: expectedId, + baselineTurnKey: this.#submittedTurn && (!threadId || (0, _thread_ids_js__rspack_import_3.BS)(threadId) === this.#submittedTurn.threadId) ? this.#submittedTurn.turnKey : undefined }); const durable = (0, _cdp_dom_js__rspack_import_2.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_3.BS)(done.conversationId) : null); if (!durable) { @@ -10355,26 +10185,13 @@ var __webpack_modules__ = { delivery: 'replied' }; } catch (error) { - const last = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); - const durable = (0, _cdp_dom_js__rspack_import_2.X8)(last.conversationId, threadId); - if (last.reply && durable) { - return { - threadId: durable, - conversationId: last.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, - reply: last.reply, - backend: 'cdp', - experimental: false, - delivery: 'replied' - }; - } + if (!(error instanceof _cdp_dom_js__rspack_import_2.aw)) throw error; return { - threadId: durable ?? (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) ? threadId : 'unknown'), - conversationId: last.conversationId || undefined, - reply: last.reply, + threadId: threadId ?? 'unknown', + reply: '', backend: 'cdp', experimental: false, - delivery: last.reply ? 'replied' : 'timeout', - ...error instanceof Error ? {} : {} + delivery: 'timeout' }; } } @@ -10431,7 +10248,8 @@ var __webpack_modules__ = { async #openAndWait(sessionId, threadId, openTimeoutMs) { await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { - timeoutMs: openTimeoutMs + timeoutMs: openTimeoutMs, + threadId }); } async #attachMainWindow() { @@ -10462,9 +10280,6 @@ var __webpack_modules__ = { return this.#session; } } - function delay(ms) { - return new Promise((resolve)=>setTimeout(resolve, ms)); - } __webpack_require__.d(__webpack_exports__, { a: ()=>CdpChatGptDesktopAdapter }); @@ -10639,6 +10454,7 @@ var __webpack_modules__ = { preferred.click(); return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; } + return { ok: false, error: 'project-not-found' }; } const buttons = Array.from(document.querySelectorAll('button')); const fallback = buttons.find((btn) => (btn.textContent || '').trim() === 'New chat'); @@ -10661,6 +10477,8 @@ var __webpack_modules__ = { const FOCUS_COMPOSER_EXPRESSION = `(() => { const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); if (!composer) return { ok: false, error: 'composer-not-found' }; + if ((composer.textContent || '').trim()) return { ok: false, error: 'composer-has-draft' }; + if (document.querySelector(${JSON.stringify(STOP_BUTTON_SELECTOR)})) return { ok: false, error: 'reply-in-progress' }; composer.focus(); return { ok: true }; })()`; @@ -10688,6 +10506,7 @@ var __webpack_modules__ = { conversationId, reply, lastTurnKey, + finalTurnKey: lastFinal?.closest(${JSON.stringify(SELECTORS.turn)})?.getAttribute(${JSON.stringify(ATTR.turnKey)}) || '', }; })()`; const CONVERSATION_ID_EXPRESSION = `(() => { @@ -10772,13 +10591,23 @@ var __webpack_modules__ = { throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); } } - async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS } = {}) { + async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS, threadId } = {}) { const deadline = Date.now() + timeoutMs; while(Date.now() < deadline){ const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { sessionId }); - if (gone) return; + if (gone) { + const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; + if (!threadId) return; + if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + const rows = await listThreadsFromDom(session, sessionId, { + limit: 200 + }); + const selected = rows.find((row)=>row.selected); + if (!current && (!selected || (0, _codex_thread_id_js__rspack_import_0.vr)(selected.threadId))) return; + } else if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; + } await delay(250); } throw new Error(`ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); @@ -10799,7 +10628,7 @@ var __webpack_modules__ = { sessionId }); if (!focused?.ok) { - throw new Error('ChatGPT Desktop composer not found ([data-codex-composer=true])'); + throw new Error(`ChatGPT Desktop composer unavailable: ${focused?.error || 'not found'}`); } } async function submitComposerWithEnter(session, sessionId) { @@ -10816,12 +10645,6 @@ var __webpack_modules__ = { }, { sessionId }); - await session.send('Input.dispatchKeyEvent', { - type: 'char', - ...base - }, { - sessionId - }); await session.send('Input.dispatchKeyEvent', { type: 'keyUp', ...base @@ -10829,17 +10652,6 @@ var __webpack_modules__ = { sessionId }); } - async function submitComposerWithButton(session, sessionId) { - const result = await session.evaluate(`(() => { - const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); - if (!btn || btn.disabled) return { ok: false }; - btn.click(); - return { ok: true }; - })()`, { - sessionId - }); - return Boolean(result?.ok); - } async function sendMessageInDom(session, sessionId, text) { await focusComposer(session, sessionId); await session.send('Input.insertText', { @@ -10847,22 +10659,28 @@ var __webpack_modules__ = { }, { sessionId }); - await submitComposerWithEnter(session, sessionId); - const sendStillVisible = await session.evaluate(`(() => { - const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); - return Boolean(btn && !btn.disabled); - })()`, { - sessionId - }); - if (sendStillVisible) { - const clicked = await submitComposerWithButton(session, sessionId); - if (clicked) return { - sentVia: 'button' - }; + try { + await submitComposerWithEnter(session, sessionId); + const deadline = Date.now() + 3000; + while(Date.now() < deadline){ + const cleared = await session.evaluate(`(() => { + const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + return Boolean(composer && !(composer.textContent || '').trim()); + })()`, { + sessionId + }); + if (cleared) return { + sentVia: 'enter' + }; + await delay(100); + } + throw new Error('Desktop composer did not acknowledge submission'); + } catch (error) { + throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), { + delivery: 'unknown', + reason: 'submission-unconfirmed' + }); } - return { - sentVia: 'enter' - }; } async function readReplyState(session, sessionId) { const state = await session.evaluate(REPLY_STATE_EXPRESSION, { @@ -10873,7 +10691,8 @@ var __webpack_modules__ = { finalAssistantCount: Number(state?.finalAssistantCount ?? 0), conversationId: String(state?.conversationId ?? ''), reply: String(state?.reply ?? ''), - lastTurnKey: String(state?.lastTurnKey ?? '') + lastTurnKey: String(state?.lastTurnKey ?? ''), + finalTurnKey: String(state?.finalTurnKey ?? '') }; } async function readConversationIdFromDom(session, sessionId) { @@ -10902,14 +10721,21 @@ var __webpack_modules__ = { } return null; } - async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0 } = {}) { + class ReplyTimeoutError extends Error { + } + async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0, expectedConversationId, baselineTurnKey } = {}) { const deadline = Date.now() + timeoutMs; let sawStop = false; const started = Date.now(); while(Date.now() < deadline){ const state = await readReplyState(session, sessionId); if (state.stopVisible) sawStop = true; - const hasNewFinal = state.finalAssistantCount > baselineFinalCount && Boolean(state.reply); + expectedConversationId ??= state.conversationId || undefined; + if (expectedConversationId && state.conversationId && durableThreadKey(state.conversationId) !== durableThreadKey(expectedConversationId)) { + throw new Error('ChatGPT Desktop selected conversation changed while waiting'); + } + const latestIsFinal = Boolean(state.finalTurnKey) && state.finalTurnKey === state.lastTurnKey; + const hasNewFinal = (state.finalAssistantCount > baselineFinalCount || sawStop) && Boolean(state.reply) && latestIsFinal && (!baselineTurnKey || state.lastTurnKey !== baselineTurnKey); if (!state.stopVisible && hasNewFinal && (sawStop || Date.now() - started > 1500)) { return { reply: state.reply, @@ -10918,14 +10744,7 @@ var __webpack_modules__ = { } await delay(200); } - const last = await readReplyState(session, sessionId); - if (!last.stopVisible && last.finalAssistantCount > baselineFinalCount && last.reply) { - return { - reply: last.reply, - conversationId: last.conversationId - }; - } - throw new Error(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); + throw new ReplyTimeoutError(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); } function normalizeTurn(raw) { const role = raw.role === 'user' || raw.role === 'status' || raw.role === 'assistant' ? raw.role : raw.assistantText ? 'assistant' : raw.userText ? 'user' : 'assistant'; @@ -11002,6 +10821,7 @@ var __webpack_modules__ = { X8: ()=>resolveDurableThreadId, YX: ()=>readReplyState, Zx: ()=>waitForLoadingTaskGone, + aw: ()=>ReplyTimeoutError, lh: ()=>sendMessageInDom, s0: ()=>startNewChatInDom, z9: ()=>waitForConversationId @@ -11032,7 +10852,11 @@ var __webpack_modules__ = { let response; try { response = await fetch(`${base}/json/version`, { - signal + signal: signal ? AbortSignal.any([ + signal, + AbortSignal.timeout(5000) + ]) : AbortSignal.timeout(5000), + redirect: 'error' }); } catch (error) { throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/version: ` + (error instanceof Error ? error.message : String(error))); @@ -11040,14 +10864,22 @@ var __webpack_modules__ = { if (!response.ok) { throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP /json/version returned HTTP ${response.status}`); } - return await response.json(); + const version = await response.json(); + if (typeof version.webSocketDebuggerUrl === 'string') { + (0, _loopback_js__rspack_import_1.jv)(version.webSocketDebuggerUrl); + } + return version; } static async fetchJsonList(port, { signal } = {}) { const base = (0, _loopback_js__rspack_import_1.NJ)(port); let response; try { response = await fetch(`${base}/json/list`, { - signal + signal: signal ? AbortSignal.any([ + signal, + AbortSignal.timeout(5000) + ]) : AbortSignal.timeout(5000), + redirect: 'error' }); } catch (error) { throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/list: ` + (error instanceof Error ? error.message : String(error))); @@ -11070,35 +10902,43 @@ var __webpack_modules__ = { throw new _errors_js__rspack_import_0.sO('CDP /json/version omitted webSocketDebuggerUrl'); } const url = (0, _loopback_js__rspack_import_1.jv)(rawUrl); - const parsed = new URL(url); - (0, _loopback_js__rspack_import_1.tb)(parsed.hostname); + signal?.throwIfAborted(); await new Promise((resolve, reject)=>{ const ws = new WebSocket(url); this.#ws = ws; + const cleanup = ()=>{ + clearTimeout(timer); + signal?.removeEventListener('abort', onAbort); + }; const onAbort = ()=>{ + cleanup(); ws.close(); - reject(new Error('CDP connect aborted')); + reject(new _errors_js__rspack_import_0.sO('CDP connect aborted or timed out')); }; + const timer = setTimeout(onAbort, 5000); signal?.addEventListener('abort', onAbort, { once: true }); ws.addEventListener('open', ()=>{ - signal?.removeEventListener('abort', onAbort); + cleanup(); resolve(); }, { once: true }); ws.addEventListener('error', ()=>{ - signal?.removeEventListener('abort', onAbort); + cleanup(); reject(new _errors_js__rspack_import_0.sO(`CDP WebSocket failed for ${url}`)); }, { once: true }); ws.addEventListener('message', (event)=>this.#onMessage(event.data)); ws.addEventListener('close', ()=>{ + cleanup(); + reject(new _errors_js__rspack_import_0.sO('CDP WebSocket closed before connecting')); this.#closed = true; for (const [, pending] of this.#pending){ - pending.reject(new Error('CDP WebSocket closed')); + clearTimeout(pending.timer); + pending.reject(new _errors_js__rspack_import_0.sO('CDP WebSocket closed')); } this.#pending.clear(); }); @@ -11118,11 +10958,22 @@ var __webpack_modules__ = { if (params !== undefined) payload.params = params; if (sessionId !== undefined) payload.sessionId = sessionId; return await new Promise((resolve, reject)=>{ + const timer = setTimeout(()=>{ + this.#pending.delete(id); + reject(new _errors_js__rspack_import_0.sO(`CDP ${method} timed out`)); + }, 10000); this.#pending.set(id, { + timer, resolve: (value)=>resolve(value), reject }); - this.#ws.send(JSON.stringify(payload)); + try { + this.#ws.send(JSON.stringify(payload)); + } catch (error) { + clearTimeout(timer); + this.#pending.delete(id); + reject(error); + } }); } async evaluate(expression, { sessionId, awaitPromise = true } = {}) { @@ -11141,6 +10992,11 @@ var __webpack_modules__ = { } close() { this.#closed = true; + for (const pending of this.#pending.values()){ + clearTimeout(pending.timer); + pending.reject(new _errors_js__rspack_import_0.sO('CDP session closed')); + } + this.#pending.clear(); this.#ws?.close(); this.#ws = null; } @@ -11151,10 +11007,11 @@ var __webpack_modules__ = { } catch { return; } - if (typeof message.id !== 'number') return; + if (!message || typeof message !== 'object' || typeof message.id !== 'number') return; const pending = this.#pending.get(message.id); if (!pending) return; this.#pending.delete(message.id); + clearTimeout(pending.timer); if (message.error) { pending.reject(new Error(message.error.message || 'CDP error')); return; @@ -11195,15 +11052,9 @@ var __webpack_modules__ = { this.name = 'CdpUnreachableError'; } } - class RemoteThreadNotLoadedError1 extends _codex_remote_control_js__rspack_import_0.Rg { - constructor(threadId, hostId = null, hostName = null){ - super(threadId, hostId, hostName); - this.name = 'RemoteThreadNotLoadedError'; - } - } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, - Rg: ()=>RemoteThreadNotLoadedError1, + Rg: ()=>_codex_remote_control_js__rspack_import_0.Rg, c$: ()=>CdpHostRejectedError, sO: ()=>CdpUnreachableError }); @@ -11222,8 +11073,7 @@ var __webpack_modules__ = { statusProbe: _app_server_fallback_js__rspack_import_1.dM, listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, listHosts: _remote_threads_js__rspack_import_4.Kl, - discoverModelProviders: _app_server_fallback_js__rspack_import_1.X, - discoverRemoteEnvironments: _app_server_fallback_js__rspack_import_1.OP + discoverModelProviders: _app_server_fallback_js__rspack_import_1.X }; class ChatGptDesktopFacade { #cdp; @@ -11279,19 +11129,25 @@ var __webpack_modules__ = { cdpError = error; } } + const remotes = this.#listRemotes(); let base = null; if (appList && cdpList) base = mergeThreadLists(appList, cdpList); else if (appList) base = appList; else if (cdpList) base = cdpList; + else if (remotes.length) base = { + backend: 'app-server', + limit, + threads: [] + }; else if (cdpError) throw cdpError; else if (appError) throw appError; else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); return finalizeThreadList(base, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, - remotes: this.#listRemotes() + remotes }); } async listHosts() { @@ -11332,30 +11188,7 @@ var __webpack_modules__ = { }); } } - let hostsSource = 'remote-thread-summaries-v3+local'; - try { - const discoverEnvs = this.#fallbacks.discoverRemoteEnvironments ?? _app_server_fallback_js__rspack_import_1.OP; - const appHosts = await discoverEnvs(); - if (appHosts.source && appHosts.hosts.length > 0) { - for (const host of appHosts.hosts){ - const existing = byId.get(host.hostId); - if (existing) { - byId.set(host.hostId, { - ...existing, - hostName: existing.hostName ?? host.hostName - }); - } else { - byId.set(host.hostId, { - hostId: host.hostId, - hostName: host.hostName, - location: 'remote', - threadCount: 0 - }); - } - } - hostsSource = `${appHosts.source}+remote-thread-summaries-v3+local`; - } - } catch {} + const hostsSource = 'remote-thread-summaries-v3+local'; const remoteCounts = new Map(); for (const thread of remotes){ remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); @@ -11388,6 +11221,12 @@ var __webpack_modules__ = { ].sort(); modelProvidersSource = 'remote-summaries-distinct'; } + modelProviders = [ + ...new Set([ + ...modelProviders, + ...remotes.map((thread)=>thread.modelProvider).filter((value)=>Boolean(value)) + ]) + ].sort(); return { hosts: withCounts, hostsSource, @@ -11413,7 +11252,7 @@ var __webpack_modules__ = { const withRemotes = finalizeThreadList(base, { limit: 10000, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, remotes: this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); @@ -11425,7 +11264,7 @@ var __webpack_modules__ = { return finalizeThreadList(filtered, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: [] }); @@ -11433,19 +11272,23 @@ var __webpack_modules__ = { const cdpList = await this.#tryCdpList({ limit }); - if (!cdpList) throw appError; + const remotes = this.#listRemotes(); + if (!cdpList && !remotes.length) throw appError; const needle = options.query.trim().toLowerCase(); const filtered = { - ...cdpList, + ...cdpList ?? { + backend: 'app-server', + limit + }, query: options.query, - threads: cdpList.threads.filter((thread)=>threadMatchesQuery(thread, needle)) + threads: (cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) }; return finalizeThreadList(filtered, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, - remotes: this.#listRemotes() + remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) }); } } @@ -11473,7 +11316,7 @@ var __webpack_modules__ = { return this.#cdp.readThread({ ...options, limit, - full: full || true + full }); } } @@ -11578,12 +11421,7 @@ var __webpack_modules__ = { }); for (const thread of cdpList.threads){ if (merged.some((row)=>(0, _thread_ids_js__rspack_import_5.LV)(row.threadId, thread.threadId))) continue; - merged.push({ - ...thread, - location: thread.location ?? 'local', - hostId: thread.hostId ?? null, - hostName: thread.hostName ?? null - }); + merged.push(thread); } return { backend: appList.backend, @@ -11596,7 +11434,20 @@ var __webpack_modules__ = { }; } function finalizeThreadList(base, { limit, host = 'all', modelProvider, groupBy, remotes }) { + const remoteById = new Map(remotes.map((thread)=>[ + (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId, + thread + ])); const locals = base.threads.map((thread)=>{ + const remote = remoteById.get((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId); + if (remote && thread.location === undefined) { + return { + ...thread, + ...remote, + selected: thread.selected, + pinned: thread.pinned || remote.pinned + }; + } const location = thread.location ?? 'local'; return { ...thread, @@ -11694,9 +11545,6 @@ var __webpack_modules__ = { } function modelProviderMatches(thread, modelProvider) { if (!modelProvider) return true; - if (!thread.modelProvider) { - return thread.location === 'remote'; - } return thread.modelProvider === modelProvider; } function threadMatchesQuery(thread, needle) { @@ -11763,6 +11611,7 @@ var __webpack_modules__ = { throw new _errors_js__rspack_import_0.c$(String(raw)); } assertLoopbackHostname(url.hostname); + if (url.username || url.password || url.hash) throw new _errors_js__rspack_import_0.c$(raw); if (url.protocol !== 'ws:' && url.protocol !== 'wss:') { throw new Error(`Expected ws(s) debugger URL, got ${url.protocol}`); } @@ -11779,7 +11628,7 @@ var __webpack_modules__ = { } const raw = (env.CHATGPT_DESKTOP_CDP_PORT || '').trim(); if (!raw) return DEFAULT_CDP_PORT; - const port = Number.parseInt(raw, 10); + const port = /^\d+$/.test(raw) ? Number(raw) : NaN; if (!Number.isInteger(port) || port < 1 || port > 65535) { throw new RangeError('CHATGPT_DESKTOP_CDP_PORT must be an integer 1-65535'); } @@ -11788,37 +11637,15 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { L0: ()=>resolveCdpPort, NJ: ()=>cdpHttpBase, - jv: ()=>forceLoopbackWebSocketUrl, - tb: ()=>assertLoopbackHostname + jv: ()=>forceLoopbackWebSocketUrl }); }, "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var node_fs__rspack_import_0 = __webpack_require__("node:fs"); - var node_os__rspack_import_1 = __webpack_require__("node:os"); - var node_path__rspack_import_2 = __webpack_require__("node:path"); - var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; - function codexGlobalStatePath(env = process.env) { - const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); - return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); - } - function loadCodexGlobalState(env = process.env) { - let raw; - try { - raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); - } catch { - return null; - } - try { - const data = JSON.parse(raw); - if (!data || typeof data !== 'object' || Array.isArray(data)) return null; - return data; - } catch { - return null; - } - } function listRemoteThreadsFromState(env = process.env) { - const data = loadCodexGlobalState(env); + const data = (0, _codex_remote_control_js__rspack_import_0.IT)(env); if (!data) return []; const hostNames = collectHostNames(data); const out = []; @@ -11836,7 +11663,7 @@ var __webpack_modules__ = { pinnedIds }); if (!mapped) continue; - const bare = (0, _thread_ids_js__rspack_import_3.nn)(mapped.threadId) ?? mapped.threadId; + const bare = (0, _thread_ids_js__rspack_import_1.nn)(mapped.threadId) ?? mapped.threadId; const dedupe = `${hostId}:${bare}`; if (seen.has(dedupe)) continue; seen.add(dedupe); @@ -11846,10 +11673,10 @@ var __webpack_modules__ = { return out; } function findRemoteThread(threadId, env = process.env) { - const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; + const bare = (0, _thread_ids_js__rspack_import_1.nn)(threadId) ?? threadId; if (!bare) return null; for (const thread of listRemoteThreadsFromState(env)){ - const id = (0, _thread_ids_js__rspack_import_3.nn)(thread.threadId) ?? thread.threadId; + const id = (0, _thread_ids_js__rspack_import_1.nn)(thread.threadId) ?? thread.threadId; if (id === bare) { return { hostId: thread.hostId, @@ -11872,7 +11699,7 @@ var __webpack_modules__ = { location: 'local', threadCount: localThreadCount }); - const data = loadCodexGlobalState(env); + const data = (0, _codex_remote_control_js__rspack_import_0.IT)(env); if (data) { const hostNames = collectHostNames(data); for (const key of Object.keys(data)){ @@ -12060,7 +11887,7 @@ var __webpack_modules__ = { function mapRemoteEntry(entry, { hostId, hostName, pinnedIds }) { if (typeof entry === 'string' && entry) { return { - threadId: (0, _thread_ids_js__rspack_import_3.BS)(entry), + threadId: (0, _thread_ids_js__rspack_import_1.BS)(entry), title: entry, pinned: pinnedIds.has(entry), selected: false, @@ -12134,7 +11961,7 @@ var __webpack_modules__ = { ]) || sectionName; const pinned = pinnedIds.has(id) || row.pinned === true || sectionId === 'Pinned' || sectionName === 'Pinned'; return { - threadId: (0, _thread_ids_js__rspack_import_3.BS)(id), + threadId: (0, _thread_ids_js__rspack_import_1.BS)(id), title, pinned, selected: false, @@ -12244,7 +12071,7 @@ var __webpack_modules__ = { const sendSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), - text: zod__rspack_import_4.YjP().min(1).max(100000), + text: zod__rspack_import_4.YjP().trim().min(1).max(100000), project: zod__rspack_import_4.YjP().min(1).max(256).optional(), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); @@ -12259,19 +12086,27 @@ var __webpack_modules__ = { zod__rspack_import_4.euz(1) ]) }).catchall(zod__rspack_import_4.Pq9()); + let operationQueue = Promise.resolve(); async function withAdapter(port, run) { - const adapter = (0, _facade_js__rspack_import_2.PP)(); - const resolved = (0, _loopback_js__rspack_import_3.L0)(process.env, port); - try { - await adapter.connect({ - port: resolved - }); - } catch {} - return run(adapter); + const operation = operationQueue.then(async ()=>{ + const adapter = (0, _facade_js__rspack_import_2.PP)(); + const resolved = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + try { + try { + await adapter.connect({ + port: resolved + }); + } catch {} + return await run(adapter); + } finally{ + await adapter.close(); + } + }); + operationQueue = operation.catch(()=>{}); + return operation; } function asResult(value) { - const cleaned = Object.fromEntries(Object.entries(value).filter(([, entry])=>entry !== undefined)); - return resultSchema.parse(cleaned); + return resultSchema.parse(JSON.parse(JSON.stringify(value))); } function mapError(error) { if (error instanceof _errors_js__rspack_import_1.EH) { @@ -12389,6 +12224,7 @@ var __webpack_modules__ = { } async function sendOperation(input) { try { + input = sendSchema.parse(input); const out = await withAdapter(input.port, (adapter)=>adapter.sendMessage({ threadId: input.threadId, text: input.text, @@ -12421,7 +12257,7 @@ var __webpack_modules__ = { if (result.error) return String(result.error); if (result.reachable === true) { const backend = result.appServerFallback && typeof result.appServerFallback === 'object' ? ` cdp + app-server probe` : ''; - return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; + return result.message ? String(result.message) : `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); if (Array.isArray(result.hosts)) { @@ -12584,11 +12420,11 @@ var __webpack_modules__ = { }; const sendFields = { ...observationFields, - correlationId: id.optional(), + correlationId: bareId.optional(), envelope: zod__rspack_import_3.zMY().optional(), hop: zod__rspack_import_3.aig().int().min(0).optional(), - replyTo: id.optional(), - expectedTurnId: id.optional(), + replyTo: bareId.optional(), + expectedTurnId: bareId.optional(), whenBusy: zod__rspack_import_3.k5n([ 'reject', 'queue', @@ -12603,8 +12439,8 @@ var __webpack_modules__ = { }).strict(); const waitSchema = zod__rspack_import_3.Ikc({ ...observationFields, - turnId: id, - messageId: id.optional(), + turnId: bareId, + messageId: bareId.optional(), maxOutputBytes: zod__rspack_import_3.aig().int().min(1).max(4194304).optional() }).strict(); const watchSchema = zod__rspack_import_3.Ikc({ @@ -40758,7 +40594,7 @@ var __webpack_modules__ = { }, { "aliases": [], - "description": "Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.", + "description": "Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.", "exitCode": "result", "options": [ { @@ -40944,7 +40780,7 @@ var __webpack_modules__ = { "send" ], "render": { - "maxElapsedMs": 180000 + "maxElapsedMs": 660000 }, "rendered": true, "routeId": "cli:chatgpt-desktop/send" @@ -44356,6 +44192,7 @@ var __webpack_modules__ = { } const turns = []; let cursor; + const seen = new Set(); for(let page = 0; page < 40 && turns.length < limit; page++){ let out; try { @@ -44363,6 +44200,7 @@ var __webpack_modules__ = { threadId: bare, limit: Math.min(100, limit - turns.length), itemsView: "full", + sortDirection: "desc", ...cursor !== undefined ? { cursor } : {} @@ -44376,8 +44214,12 @@ var __webpack_modules__ = { throw new CodexProtocolError("thread/turns/list", "missing `data` array"); } for (const row of out.data)turns.push(row); - if (out.nextCursor == null || typeof out.nextCursor !== "string") break; - cursor = out.nextCursor; + cursor = out.nextCursor ?? null; + if (cursor === null) break; + if (typeof cursor !== "string" || !cursor || seen.has(cursor)) { + throw new CodexProtocolError("thread/turns/list", "invalid or repeated cursor"); + } + seen.add(cursor); } return { threadId: bare, @@ -45394,6 +45236,7 @@ var __webpack_modules__ = { return String(error); } __webpack_require__.d(__webpack_exports__, { + IT: ()=>loadCodexGlobalState, R3: ()=>mapRemoteThreadError, Rg: ()=>RemoteThreadNotLoadedError1 }); @@ -45403,7 +45246,7 @@ var __webpack_modules__ = { const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; const ID_PATTERN = /^[A-Za-z0-9_.:-]{1,128}$/; function isTemporaryDesktopThreadId(threadId) { - return typeof threadId === 'string' && threadId.startsWith(TEMP_THREAD_ID_PREFIX); + return typeof threadId === 'string' && (threadId.startsWith(TEMP_THREAD_ID_PREFIX) || threadId.startsWith('client-new-thread:')); } function normalizeCodexThreadId1(threadId) { if (typeof threadId !== 'string' || !threadId) { @@ -45418,9 +45261,6 @@ var __webpack_modules__ = { } return bare; } - function hasLocalThreadPrefix(threadId) { - return typeof threadId === 'string' && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) && !isTemporaryDesktopThreadId(threadId); - } __webpack_require__.d(__webpack_exports__, { SX: ()=>normalizeCodexThreadId1, vr: ()=>isTemporaryDesktopThreadId diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index 23816c1..7a1cb80 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8136,46 +8136,7 @@ var __webpack_modules__ = { modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } - const MODEL_PROVIDER_LIST_METHODS = [ - 'modelProvider/list', - 'model/providers/list', - 'models/providers/list', - 'account/modelProviders/list', - 'config/modelProviders/list', - 'provider/list' - ]; - const REMOTE_ENVIRONMENT_LIST_METHODS = [ - 'remoteEnvironment/list', - 'remote/environments/list', - 'environment/list', - 'remoteControl/hosts/list', - 'remote/hosts/list', - 'hosts/list' - ]; async function discoverModelProviders() { - const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); - try { - for (const method of MODEL_PROVIDER_LIST_METHODS){ - try { - const result = await client.request(method, {}); - const providers = normalizeNamedList(result, [ - 'id', - 'name', - 'provider', - 'modelProvider', - 'slug' - ]); - if (providers.length > 0) { - return { - providers, - source: `app-server:${method}` - }; - } - } catch {} - } - } finally{ - client.close(); - } const providers = new Set(); let cursor; for(let page = 0; page < 20; page++){ @@ -8199,113 +8160,6 @@ var __webpack_modules__ = { source: 'thread/list-distinct' }; } - async function discoverRemoteEnvironments() { - const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); - try { - for (const method of REMOTE_ENVIRONMENT_LIST_METHODS){ - try { - const result = await client.request(method, {}); - const hosts = normalizeHostEntries(result); - if (hosts.length > 0) { - return { - hosts, - source: `app-server:${method}` - }; - } - } catch {} - } - } finally{ - client.close(); - } - return { - hosts: [], - source: null - }; - } - function normalizeNamedList(result, idKeys) { - const raw = listPayload(result); - const out = []; - for (const entry of raw){ - if (typeof entry === 'string' && entry) out.push(entry); - else if (entry && typeof entry === 'object') { - const row = entry; - for (const key of idKeys){ - if (typeof row[key] === 'string' && row[key]) { - out.push(String(row[key])); - break; - } - } - } - } - return [ - ...new Set(out) - ].sort(); - } - function normalizeHostEntries(result) { - const raw = listPayload(result); - const out = []; - for (const entry of raw){ - if (typeof entry === 'string' && entry) { - out.push({ - hostId: entry, - hostName: null - }); - continue; - } - if (!entry || typeof entry !== 'object') continue; - const row = entry; - let hostId = null; - for (const key of [ - 'hostId', - 'id', - 'uuid', - 'environmentId', - 'envId' - ]){ - if (typeof row[key] === 'string' && row[key]) { - hostId = String(row[key]); - break; - } - } - if (!hostId) continue; - let hostName = null; - for (const key of [ - 'hostName', - 'name', - 'displayName', - 'envName', - 'label', - 'title' - ]){ - if (typeof row[key] === 'string' && row[key]) { - hostName = String(row[key]); - break; - } - } - out.push({ - hostId, - hostName - }); - } - return out; - } - function listPayload(result) { - if (Array.isArray(result)) return result; - if (!result || typeof result !== 'object') return []; - const record = result; - for (const key of [ - 'data', - 'providers', - 'modelProviders', - 'hosts', - 'environments', - 'remoteEnvironments', - 'items' - ]){ - if (Array.isArray(record[key])) return record[key]; - } - return []; - } async function appServerReadThread({ threadId, limit = 100, full = false }) { const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); @@ -8430,85 +8284,46 @@ var __webpack_modules__ = { async function listTurnsFull(client, threadId, { limit, full }) { const collected = []; let cursor; - try { - for(let page = 0; page < 40; page++){ - const result = await client.request('thread/turns/list', { + let itemsView = true; + let method = 'thread/turns/list'; + const seen = new Set(); + while(collected.length < limit){ + let result; + try { + result = await client.request(method, { threadId, - limit: 100, - itemsView: 'full', - ...cursor ? { + limit: Math.min(100, limit - collected.length), + sortDirection: full ? 'asc' : 'desc', + ...method === 'thread/turns/list' && itemsView ? { + itemsView: 'full' + } : {}, + ...cursor !== undefined ? { cursor } : {} }); - if (!Array.isArray(result.data)) { - throw new Error(`thread/turns/list missing data array for ${threadId}`); + } catch (error) { + const code = error?.rpc?.code; + if (collected.length === 0 && code === -32602 && itemsView) { + itemsView = false; + continue; } - collected.push(...result.data); - if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; - cursor = result.nextCursor; - if (!full && collected.length >= limit) break; - } - } catch (error) { - if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); - if (collected.length === 0) { - return listTurnsFallback(client, threadId, { - limit, - full - }); - } - throw error; - } - if (collected.length === 0) { - return listTurnsFallback(client, threadId, { - limit, - full - }); - } - return sliceTurns(normalizeTurns(collected), { - limit, - full - }); - } - async function listTurnsFallback(client, threadId, { limit, full }) { - for (const method of [ - 'thread/turns/list', - 'thread/items/list' - ]){ - try { - const collected = []; - let cursor; - for(let page = 0; page < 40; page++){ - const params = { - threadId, - limit: 100, - ...cursor ? { - cursor - } : {} - }; - if (method === 'thread/turns/list') params.itemsView = 'full'; - const result = await client.request(method, params); - if (!Array.isArray(result.data)) break; - collected.push(...result.data); - if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; - cursor = result.nextCursor; - if (!full && collected.length >= limit) break; - } - if (collected.length > 0) { - return sliceTurns(normalizeTurns(collected), { - limit, - full - }); + if (collected.length === 0 && code === -32601 && method === 'thread/turns/list') { + method = 'thread/items/list'; + continue; } - } catch (error) { - if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + throw maybeRemoteThreadError(error, threadId); + } + if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); + collected.push(...result.data); + if (result.nextCursor == null) break; + if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { + throw new Error(`${method} returned an invalid or repeated cursor`); } + seen.add(result.nextCursor); + cursor = result.nextCursor; } - throw new Error(`app-server has no turn history for thread ${threadId}`); - } - function sliceTurns(turns, { limit, full }) { - if (limit <= 0) return turns; - if (full) return turns.slice(0, limit); - return turns.slice(-limit); + const turns = normalizeTurns(collected.slice(0, limit)); + return full ? turns : turns.reverse(); } function normalizeTurns(raw) { const turns = []; @@ -8631,7 +8446,6 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, - OP: ()=>discoverRemoteEnvironments, X: ()=>discoverModelProviders, aI: ()=>appServerSearchThreads, dM: ()=>appServerStatusProbe @@ -8649,6 +8463,7 @@ var __webpack_modules__ = { #version = null; #pageSessionId = null; #mainTargetId = null; + #submittedTurn = null; async connect({ port }) { await this.close(); this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); @@ -8705,25 +8520,40 @@ var __webpack_modules__ = { await (0, _cdp_dom_js__rspack_import_2.s0)(this.#requireSession(), sessionId, { project }); - await delay(300); + await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { + timeoutMs: openTimeoutMs, + threadId: 'new' + }); const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { limit: 20 }); const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); if (temp) temporaryThreadId = temp.threadId; } + const before = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); let conversationId; if (startedNew || threadId && (0, _thread_ids_js__rspack_import_3.vr)(threadId)) { const resolveMs = Math.min(openTimeoutMs, 60000); - conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { - timeoutMs: resolveMs - }); + try { + conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { + timeoutMs: resolveMs + }); + } catch (error) { + throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), { + delivery: 'unknown', + reason: 'conversation-id-unresolved' + }); + } } const durable = (0, _cdp_dom_js__rspack_import_2.X8)(conversationId, threadId); if (!durable) { throw new Error('ChatGPT Desktop send accepted but no durable conversation id was available; ' + 'refusing to return a local:client-new-thread:* id as threadId'); } + this.#submittedTurn = { + threadId: durable, + turnKey: before.lastTurnKey + }; return { threadId: durable, temporaryThreadId, @@ -8737,17 +8567,17 @@ var __webpack_modules__ = { }; } async waitForReply({ threadId, timeoutMs = 120000 }) { + const deadline = Date.now() + timeoutMs; const sessionId = await this.#ensurePageSession(); + const expectedId = threadId && threadId !== 'new' ? (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? undefined : this.#submittedTurn ? (0, _thread_ids_js__rspack_import_3.nn)(this.#submittedTurn.threadId) ?? undefined : undefined; if (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) && threadId !== 'new') { - try { - await this.#openAndWait(sessionId, threadId, 90000); - } catch {} + await this.#openAndWait(sessionId, threadId, Math.min(timeoutMs, 90000)); } - const baseline = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); try { const done = await (0, _cdp_dom_js__rspack_import_2.FG)(this.#requireSession(), sessionId, { - timeoutMs, - baselineFinalCount: baseline.finalAssistantCount + timeoutMs: Math.max(0, deadline - Date.now()), + expectedConversationId: expectedId, + baselineTurnKey: this.#submittedTurn && (!threadId || (0, _thread_ids_js__rspack_import_3.BS)(threadId) === this.#submittedTurn.threadId) ? this.#submittedTurn.turnKey : undefined }); const durable = (0, _cdp_dom_js__rspack_import_2.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_3.BS)(done.conversationId) : null); if (!durable) { @@ -8762,26 +8592,13 @@ var __webpack_modules__ = { delivery: 'replied' }; } catch (error) { - const last = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); - const durable = (0, _cdp_dom_js__rspack_import_2.X8)(last.conversationId, threadId); - if (last.reply && durable) { - return { - threadId: durable, - conversationId: last.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, - reply: last.reply, - backend: 'cdp', - experimental: false, - delivery: 'replied' - }; - } + if (!(error instanceof _cdp_dom_js__rspack_import_2.aw)) throw error; return { - threadId: durable ?? (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) ? threadId : 'unknown'), - conversationId: last.conversationId || undefined, - reply: last.reply, + threadId: threadId ?? 'unknown', + reply: '', backend: 'cdp', experimental: false, - delivery: last.reply ? 'replied' : 'timeout', - ...error instanceof Error ? {} : {} + delivery: 'timeout' }; } } @@ -8838,7 +8655,8 @@ var __webpack_modules__ = { async #openAndWait(sessionId, threadId, openTimeoutMs) { await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { - timeoutMs: openTimeoutMs + timeoutMs: openTimeoutMs, + threadId }); } async #attachMainWindow() { @@ -8869,9 +8687,6 @@ var __webpack_modules__ = { return this.#session; } } - function delay(ms) { - return new Promise((resolve)=>setTimeout(resolve, ms)); - } __webpack_require__.d(__webpack_exports__, { a: ()=>CdpChatGptDesktopAdapter }); @@ -9046,6 +8861,7 @@ var __webpack_modules__ = { preferred.click(); return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; } + return { ok: false, error: 'project-not-found' }; } const buttons = Array.from(document.querySelectorAll('button')); const fallback = buttons.find((btn) => (btn.textContent || '').trim() === 'New chat'); @@ -9068,6 +8884,8 @@ var __webpack_modules__ = { const FOCUS_COMPOSER_EXPRESSION = `(() => { const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); if (!composer) return { ok: false, error: 'composer-not-found' }; + if ((composer.textContent || '').trim()) return { ok: false, error: 'composer-has-draft' }; + if (document.querySelector(${JSON.stringify(STOP_BUTTON_SELECTOR)})) return { ok: false, error: 'reply-in-progress' }; composer.focus(); return { ok: true }; })()`; @@ -9095,6 +8913,7 @@ var __webpack_modules__ = { conversationId, reply, lastTurnKey, + finalTurnKey: lastFinal?.closest(${JSON.stringify(SELECTORS.turn)})?.getAttribute(${JSON.stringify(ATTR.turnKey)}) || '', }; })()`; const CONVERSATION_ID_EXPRESSION = `(() => { @@ -9179,13 +8998,23 @@ var __webpack_modules__ = { throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); } } - async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS } = {}) { + async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS, threadId } = {}) { const deadline = Date.now() + timeoutMs; while(Date.now() < deadline){ const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { sessionId }); - if (gone) return; + if (gone) { + const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; + if (!threadId) return; + if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + const rows = await listThreadsFromDom(session, sessionId, { + limit: 200 + }); + const selected = rows.find((row)=>row.selected); + if (!current && (!selected || (0, _codex_thread_id_js__rspack_import_0.vr)(selected.threadId))) return; + } else if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; + } await delay(250); } throw new Error(`ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); @@ -9206,7 +9035,7 @@ var __webpack_modules__ = { sessionId }); if (!focused?.ok) { - throw new Error('ChatGPT Desktop composer not found ([data-codex-composer=true])'); + throw new Error(`ChatGPT Desktop composer unavailable: ${focused?.error || 'not found'}`); } } async function submitComposerWithEnter(session, sessionId) { @@ -9223,12 +9052,6 @@ var __webpack_modules__ = { }, { sessionId }); - await session.send('Input.dispatchKeyEvent', { - type: 'char', - ...base - }, { - sessionId - }); await session.send('Input.dispatchKeyEvent', { type: 'keyUp', ...base @@ -9236,17 +9059,6 @@ var __webpack_modules__ = { sessionId }); } - async function submitComposerWithButton(session, sessionId) { - const result = await session.evaluate(`(() => { - const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); - if (!btn || btn.disabled) return { ok: false }; - btn.click(); - return { ok: true }; - })()`, { - sessionId - }); - return Boolean(result?.ok); - } async function sendMessageInDom(session, sessionId, text) { await focusComposer(session, sessionId); await session.send('Input.insertText', { @@ -9254,22 +9066,28 @@ var __webpack_modules__ = { }, { sessionId }); - await submitComposerWithEnter(session, sessionId); - const sendStillVisible = await session.evaluate(`(() => { - const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); - return Boolean(btn && !btn.disabled); - })()`, { - sessionId - }); - if (sendStillVisible) { - const clicked = await submitComposerWithButton(session, sessionId); - if (clicked) return { - sentVia: 'button' - }; + try { + await submitComposerWithEnter(session, sessionId); + const deadline = Date.now() + 3000; + while(Date.now() < deadline){ + const cleared = await session.evaluate(`(() => { + const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + return Boolean(composer && !(composer.textContent || '').trim()); + })()`, { + sessionId + }); + if (cleared) return { + sentVia: 'enter' + }; + await delay(100); + } + throw new Error('Desktop composer did not acknowledge submission'); + } catch (error) { + throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), { + delivery: 'unknown', + reason: 'submission-unconfirmed' + }); } - return { - sentVia: 'enter' - }; } async function readReplyState(session, sessionId) { const state = await session.evaluate(REPLY_STATE_EXPRESSION, { @@ -9280,7 +9098,8 @@ var __webpack_modules__ = { finalAssistantCount: Number(state?.finalAssistantCount ?? 0), conversationId: String(state?.conversationId ?? ''), reply: String(state?.reply ?? ''), - lastTurnKey: String(state?.lastTurnKey ?? '') + lastTurnKey: String(state?.lastTurnKey ?? ''), + finalTurnKey: String(state?.finalTurnKey ?? '') }; } async function readConversationIdFromDom(session, sessionId) { @@ -9309,14 +9128,21 @@ var __webpack_modules__ = { } return null; } - async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0 } = {}) { + class ReplyTimeoutError extends Error { + } + async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0, expectedConversationId, baselineTurnKey } = {}) { const deadline = Date.now() + timeoutMs; let sawStop = false; const started = Date.now(); while(Date.now() < deadline){ const state = await readReplyState(session, sessionId); if (state.stopVisible) sawStop = true; - const hasNewFinal = state.finalAssistantCount > baselineFinalCount && Boolean(state.reply); + expectedConversationId ??= state.conversationId || undefined; + if (expectedConversationId && state.conversationId && durableThreadKey(state.conversationId) !== durableThreadKey(expectedConversationId)) { + throw new Error('ChatGPT Desktop selected conversation changed while waiting'); + } + const latestIsFinal = Boolean(state.finalTurnKey) && state.finalTurnKey === state.lastTurnKey; + const hasNewFinal = (state.finalAssistantCount > baselineFinalCount || sawStop) && Boolean(state.reply) && latestIsFinal && (!baselineTurnKey || state.lastTurnKey !== baselineTurnKey); if (!state.stopVisible && hasNewFinal && (sawStop || Date.now() - started > 1500)) { return { reply: state.reply, @@ -9325,14 +9151,7 @@ var __webpack_modules__ = { } await delay(200); } - const last = await readReplyState(session, sessionId); - if (!last.stopVisible && last.finalAssistantCount > baselineFinalCount && last.reply) { - return { - reply: last.reply, - conversationId: last.conversationId - }; - } - throw new Error(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); + throw new ReplyTimeoutError(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); } function normalizeTurn(raw) { const role = raw.role === 'user' || raw.role === 'status' || raw.role === 'assistant' ? raw.role : raw.assistantText ? 'assistant' : raw.userText ? 'user' : 'assistant'; @@ -9409,6 +9228,7 @@ var __webpack_modules__ = { X8: ()=>resolveDurableThreadId, YX: ()=>readReplyState, Zx: ()=>waitForLoadingTaskGone, + aw: ()=>ReplyTimeoutError, lh: ()=>sendMessageInDom, s0: ()=>startNewChatInDom, z9: ()=>waitForConversationId @@ -9439,7 +9259,11 @@ var __webpack_modules__ = { let response; try { response = await fetch(`${base}/json/version`, { - signal + signal: signal ? AbortSignal.any([ + signal, + AbortSignal.timeout(5000) + ]) : AbortSignal.timeout(5000), + redirect: 'error' }); } catch (error) { throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/version: ` + (error instanceof Error ? error.message : String(error))); @@ -9447,14 +9271,22 @@ var __webpack_modules__ = { if (!response.ok) { throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP /json/version returned HTTP ${response.status}`); } - return await response.json(); + const version = await response.json(); + if (typeof version.webSocketDebuggerUrl === 'string') { + (0, _loopback_js__rspack_import_1.jv)(version.webSocketDebuggerUrl); + } + return version; } static async fetchJsonList(port, { signal } = {}) { const base = (0, _loopback_js__rspack_import_1.NJ)(port); let response; try { response = await fetch(`${base}/json/list`, { - signal + signal: signal ? AbortSignal.any([ + signal, + AbortSignal.timeout(5000) + ]) : AbortSignal.timeout(5000), + redirect: 'error' }); } catch (error) { throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/list: ` + (error instanceof Error ? error.message : String(error))); @@ -9477,35 +9309,43 @@ var __webpack_modules__ = { throw new _errors_js__rspack_import_0.sO('CDP /json/version omitted webSocketDebuggerUrl'); } const url = (0, _loopback_js__rspack_import_1.jv)(rawUrl); - const parsed = new URL(url); - (0, _loopback_js__rspack_import_1.tb)(parsed.hostname); + signal?.throwIfAborted(); await new Promise((resolve, reject)=>{ const ws = new WebSocket(url); this.#ws = ws; + const cleanup = ()=>{ + clearTimeout(timer); + signal?.removeEventListener('abort', onAbort); + }; const onAbort = ()=>{ + cleanup(); ws.close(); - reject(new Error('CDP connect aborted')); + reject(new _errors_js__rspack_import_0.sO('CDP connect aborted or timed out')); }; + const timer = setTimeout(onAbort, 5000); signal?.addEventListener('abort', onAbort, { once: true }); ws.addEventListener('open', ()=>{ - signal?.removeEventListener('abort', onAbort); + cleanup(); resolve(); }, { once: true }); ws.addEventListener('error', ()=>{ - signal?.removeEventListener('abort', onAbort); + cleanup(); reject(new _errors_js__rspack_import_0.sO(`CDP WebSocket failed for ${url}`)); }, { once: true }); ws.addEventListener('message', (event)=>this.#onMessage(event.data)); ws.addEventListener('close', ()=>{ + cleanup(); + reject(new _errors_js__rspack_import_0.sO('CDP WebSocket closed before connecting')); this.#closed = true; for (const [, pending] of this.#pending){ - pending.reject(new Error('CDP WebSocket closed')); + clearTimeout(pending.timer); + pending.reject(new _errors_js__rspack_import_0.sO('CDP WebSocket closed')); } this.#pending.clear(); }); @@ -9525,11 +9365,22 @@ var __webpack_modules__ = { if (params !== undefined) payload.params = params; if (sessionId !== undefined) payload.sessionId = sessionId; return await new Promise((resolve, reject)=>{ + const timer = setTimeout(()=>{ + this.#pending.delete(id); + reject(new _errors_js__rspack_import_0.sO(`CDP ${method} timed out`)); + }, 10000); this.#pending.set(id, { + timer, resolve: (value)=>resolve(value), reject }); - this.#ws.send(JSON.stringify(payload)); + try { + this.#ws.send(JSON.stringify(payload)); + } catch (error) { + clearTimeout(timer); + this.#pending.delete(id); + reject(error); + } }); } async evaluate(expression, { sessionId, awaitPromise = true } = {}) { @@ -9548,6 +9399,11 @@ var __webpack_modules__ = { } close() { this.#closed = true; + for (const pending of this.#pending.values()){ + clearTimeout(pending.timer); + pending.reject(new _errors_js__rspack_import_0.sO('CDP session closed')); + } + this.#pending.clear(); this.#ws?.close(); this.#ws = null; } @@ -9558,10 +9414,11 @@ var __webpack_modules__ = { } catch { return; } - if (typeof message.id !== 'number') return; + if (!message || typeof message !== 'object' || typeof message.id !== 'number') return; const pending = this.#pending.get(message.id); if (!pending) return; this.#pending.delete(message.id); + clearTimeout(pending.timer); if (message.error) { pending.reject(new Error(message.error.message || 'CDP error')); return; @@ -9602,15 +9459,9 @@ var __webpack_modules__ = { this.name = 'CdpUnreachableError'; } } - class RemoteThreadNotLoadedError1 extends _codex_remote_control_js__rspack_import_0.Rg { - constructor(threadId, hostId = null, hostName = null){ - super(threadId, hostId, hostName); - this.name = 'RemoteThreadNotLoadedError'; - } - } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, - Rg: ()=>RemoteThreadNotLoadedError1, + Rg: ()=>_codex_remote_control_js__rspack_import_0.Rg, c$: ()=>CdpHostRejectedError, sO: ()=>CdpUnreachableError }); @@ -9629,8 +9480,7 @@ var __webpack_modules__ = { statusProbe: _app_server_fallback_js__rspack_import_1.dM, listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, listHosts: _remote_threads_js__rspack_import_4.Kl, - discoverModelProviders: _app_server_fallback_js__rspack_import_1.X, - discoverRemoteEnvironments: _app_server_fallback_js__rspack_import_1.OP + discoverModelProviders: _app_server_fallback_js__rspack_import_1.X }; class ChatGptDesktopFacade { #cdp; @@ -9686,19 +9536,25 @@ var __webpack_modules__ = { cdpError = error; } } + const remotes = this.#listRemotes(); let base = null; if (appList && cdpList) base = mergeThreadLists(appList, cdpList); else if (appList) base = appList; else if (cdpList) base = cdpList; + else if (remotes.length) base = { + backend: 'app-server', + limit, + threads: [] + }; else if (cdpError) throw cdpError; else if (appError) throw appError; else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); return finalizeThreadList(base, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, - remotes: this.#listRemotes() + remotes }); } async listHosts() { @@ -9739,30 +9595,7 @@ var __webpack_modules__ = { }); } } - let hostsSource = 'remote-thread-summaries-v3+local'; - try { - const discoverEnvs = this.#fallbacks.discoverRemoteEnvironments ?? _app_server_fallback_js__rspack_import_1.OP; - const appHosts = await discoverEnvs(); - if (appHosts.source && appHosts.hosts.length > 0) { - for (const host of appHosts.hosts){ - const existing = byId.get(host.hostId); - if (existing) { - byId.set(host.hostId, { - ...existing, - hostName: existing.hostName ?? host.hostName - }); - } else { - byId.set(host.hostId, { - hostId: host.hostId, - hostName: host.hostName, - location: 'remote', - threadCount: 0 - }); - } - } - hostsSource = `${appHosts.source}+remote-thread-summaries-v3+local`; - } - } catch {} + const hostsSource = 'remote-thread-summaries-v3+local'; const remoteCounts = new Map(); for (const thread of remotes){ remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); @@ -9795,6 +9628,12 @@ var __webpack_modules__ = { ].sort(); modelProvidersSource = 'remote-summaries-distinct'; } + modelProviders = [ + ...new Set([ + ...modelProviders, + ...remotes.map((thread)=>thread.modelProvider).filter((value)=>Boolean(value)) + ]) + ].sort(); return { hosts: withCounts, hostsSource, @@ -9820,7 +9659,7 @@ var __webpack_modules__ = { const withRemotes = finalizeThreadList(base, { limit: 10000, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, remotes: this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); @@ -9832,7 +9671,7 @@ var __webpack_modules__ = { return finalizeThreadList(filtered, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: [] }); @@ -9840,19 +9679,23 @@ var __webpack_modules__ = { const cdpList = await this.#tryCdpList({ limit }); - if (!cdpList) throw appError; + const remotes = this.#listRemotes(); + if (!cdpList && !remotes.length) throw appError; const needle = options.query.trim().toLowerCase(); const filtered = { - ...cdpList, + ...cdpList ?? { + backend: 'app-server', + limit + }, query: options.query, - threads: cdpList.threads.filter((thread)=>threadMatchesQuery(thread, needle)) + threads: (cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) }; return finalizeThreadList(filtered, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, - remotes: this.#listRemotes() + remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) }); } } @@ -9880,7 +9723,7 @@ var __webpack_modules__ = { return this.#cdp.readThread({ ...options, limit, - full: full || true + full }); } } @@ -9985,12 +9828,7 @@ var __webpack_modules__ = { }); for (const thread of cdpList.threads){ if (merged.some((row)=>(0, _thread_ids_js__rspack_import_5.LV)(row.threadId, thread.threadId))) continue; - merged.push({ - ...thread, - location: thread.location ?? 'local', - hostId: thread.hostId ?? null, - hostName: thread.hostName ?? null - }); + merged.push(thread); } return { backend: appList.backend, @@ -10003,7 +9841,20 @@ var __webpack_modules__ = { }; } function finalizeThreadList(base, { limit, host = 'all', modelProvider, groupBy, remotes }) { + const remoteById = new Map(remotes.map((thread)=>[ + (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId, + thread + ])); const locals = base.threads.map((thread)=>{ + const remote = remoteById.get((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId); + if (remote && thread.location === undefined) { + return { + ...thread, + ...remote, + selected: thread.selected, + pinned: thread.pinned || remote.pinned + }; + } const location = thread.location ?? 'local'; return { ...thread, @@ -10101,9 +9952,6 @@ var __webpack_modules__ = { } function modelProviderMatches(thread, modelProvider) { if (!modelProvider) return true; - if (!thread.modelProvider) { - return thread.location === 'remote'; - } return thread.modelProvider === modelProvider; } function threadMatchesQuery(thread, needle) { @@ -10170,6 +10018,7 @@ var __webpack_modules__ = { throw new _errors_js__rspack_import_0.c$(String(raw)); } assertLoopbackHostname(url.hostname); + if (url.username || url.password || url.hash) throw new _errors_js__rspack_import_0.c$(raw); if (url.protocol !== 'ws:' && url.protocol !== 'wss:') { throw new Error(`Expected ws(s) debugger URL, got ${url.protocol}`); } @@ -10186,7 +10035,7 @@ var __webpack_modules__ = { } const raw = (env.CHATGPT_DESKTOP_CDP_PORT || '').trim(); if (!raw) return DEFAULT_CDP_PORT; - const port = Number.parseInt(raw, 10); + const port = /^\d+$/.test(raw) ? Number(raw) : NaN; if (!Number.isInteger(port) || port < 1 || port > 65535) { throw new RangeError('CHATGPT_DESKTOP_CDP_PORT must be an integer 1-65535'); } @@ -10195,37 +10044,15 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { L0: ()=>resolveCdpPort, NJ: ()=>cdpHttpBase, - jv: ()=>forceLoopbackWebSocketUrl, - tb: ()=>assertLoopbackHostname + jv: ()=>forceLoopbackWebSocketUrl }); }, "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var node_fs__rspack_import_0 = __webpack_require__("node:fs"); - var node_os__rspack_import_1 = __webpack_require__("node:os"); - var node_path__rspack_import_2 = __webpack_require__("node:path"); - var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; - function codexGlobalStatePath(env = process.env) { - const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); - return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); - } - function loadCodexGlobalState(env = process.env) { - let raw; - try { - raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); - } catch { - return null; - } - try { - const data = JSON.parse(raw); - if (!data || typeof data !== 'object' || Array.isArray(data)) return null; - return data; - } catch { - return null; - } - } function listRemoteThreadsFromState(env = process.env) { - const data = loadCodexGlobalState(env); + const data = (0, _codex_remote_control_js__rspack_import_0.IT)(env); if (!data) return []; const hostNames = collectHostNames(data); const out = []; @@ -10243,7 +10070,7 @@ var __webpack_modules__ = { pinnedIds }); if (!mapped) continue; - const bare = (0, _thread_ids_js__rspack_import_3.nn)(mapped.threadId) ?? mapped.threadId; + const bare = (0, _thread_ids_js__rspack_import_1.nn)(mapped.threadId) ?? mapped.threadId; const dedupe = `${hostId}:${bare}`; if (seen.has(dedupe)) continue; seen.add(dedupe); @@ -10253,10 +10080,10 @@ var __webpack_modules__ = { return out; } function findRemoteThread(threadId, env = process.env) { - const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; + const bare = (0, _thread_ids_js__rspack_import_1.nn)(threadId) ?? threadId; if (!bare) return null; for (const thread of listRemoteThreadsFromState(env)){ - const id = (0, _thread_ids_js__rspack_import_3.nn)(thread.threadId) ?? thread.threadId; + const id = (0, _thread_ids_js__rspack_import_1.nn)(thread.threadId) ?? thread.threadId; if (id === bare) { return { hostId: thread.hostId, @@ -10279,7 +10106,7 @@ var __webpack_modules__ = { location: 'local', threadCount: localThreadCount }); - const data = loadCodexGlobalState(env); + const data = (0, _codex_remote_control_js__rspack_import_0.IT)(env); if (data) { const hostNames = collectHostNames(data); for (const key of Object.keys(data)){ @@ -10467,7 +10294,7 @@ var __webpack_modules__ = { function mapRemoteEntry(entry, { hostId, hostName, pinnedIds }) { if (typeof entry === 'string' && entry) { return { - threadId: (0, _thread_ids_js__rspack_import_3.BS)(entry), + threadId: (0, _thread_ids_js__rspack_import_1.BS)(entry), title: entry, pinned: pinnedIds.has(entry), selected: false, @@ -10541,7 +10368,7 @@ var __webpack_modules__ = { ]) || sectionName; const pinned = pinnedIds.has(id) || row.pinned === true || sectionId === 'Pinned' || sectionName === 'Pinned'; return { - threadId: (0, _thread_ids_js__rspack_import_3.BS)(id), + threadId: (0, _thread_ids_js__rspack_import_1.BS)(id), title, pinned, selected: false, @@ -10651,7 +10478,7 @@ var __webpack_modules__ = { const sendSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), - text: zod__rspack_import_4.YjP().min(1).max(100000), + text: zod__rspack_import_4.YjP().trim().min(1).max(100000), project: zod__rspack_import_4.YjP().min(1).max(256).optional(), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); @@ -10666,19 +10493,27 @@ var __webpack_modules__ = { zod__rspack_import_4.euz(1) ]) }).catchall(zod__rspack_import_4.Pq9()); + let operationQueue = Promise.resolve(); async function withAdapter(port, run) { - const adapter = (0, _facade_js__rspack_import_2.PP)(); - const resolved = (0, _loopback_js__rspack_import_3.L0)(process.env, port); - try { - await adapter.connect({ - port: resolved - }); - } catch {} - return run(adapter); + const operation = operationQueue.then(async ()=>{ + const adapter = (0, _facade_js__rspack_import_2.PP)(); + const resolved = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + try { + try { + await adapter.connect({ + port: resolved + }); + } catch {} + return await run(adapter); + } finally{ + await adapter.close(); + } + }); + operationQueue = operation.catch(()=>{}); + return operation; } function asResult(value) { - const cleaned = Object.fromEntries(Object.entries(value).filter(([, entry])=>entry !== undefined)); - return resultSchema.parse(cleaned); + return resultSchema.parse(JSON.parse(JSON.stringify(value))); } function mapError(error) { if (error instanceof _errors_js__rspack_import_1.EH) { @@ -10796,6 +10631,7 @@ var __webpack_modules__ = { } async function sendOperation(input) { try { + input = sendSchema.parse(input); const out = await withAdapter(input.port, (adapter)=>adapter.sendMessage({ threadId: input.threadId, text: input.text, @@ -10828,7 +10664,7 @@ var __webpack_modules__ = { if (result.error) return String(result.error); if (result.reachable === true) { const backend = result.appServerFallback && typeof result.appServerFallback === 'object' ? ` cdp + app-server probe` : ''; - return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; + return result.message ? String(result.message) : `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); if (Array.isArray(result.hosts)) { @@ -10999,11 +10835,11 @@ var __webpack_modules__ = { }; const sendFields = { ...observationFields, - correlationId: id.optional(), + correlationId: bareId.optional(), envelope: zod__rspack_import_3.zMY().optional(), hop: zod__rspack_import_3.aig().int().min(0).optional(), - replyTo: id.optional(), - expectedTurnId: id.optional(), + replyTo: bareId.optional(), + expectedTurnId: bareId.optional(), whenBusy: zod__rspack_import_3.k5n([ 'reject', 'queue', @@ -11018,8 +10854,8 @@ var __webpack_modules__ = { }).strict(); const waitSchema = zod__rspack_import_3.Ikc({ ...observationFields, - turnId: id, - messageId: id.optional(), + turnId: bareId, + messageId: bareId.optional(), maxOutputBytes: zod__rspack_import_3.aig().int().min(1).max(4194304).optional() }).strict(); const watchSchema = zod__rspack_import_3.Ikc({ @@ -11512,7 +11348,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list hosts', - description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.', + description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource', annotations: { readOnlyHint: true }, @@ -24812,6 +24648,7 @@ var __webpack_modules__ = { } const turns = []; let cursor; + const seen = new Set(); for(let page = 0; page < 40 && turns.length < limit; page++){ let out; try { @@ -24819,6 +24656,7 @@ var __webpack_modules__ = { threadId: bare, limit: Math.min(100, limit - turns.length), itemsView: "full", + sortDirection: "desc", ...cursor !== undefined ? { cursor } : {} @@ -24832,8 +24670,12 @@ var __webpack_modules__ = { throw new CodexProtocolError("thread/turns/list", "missing `data` array"); } for (const row of out.data)turns.push(row); - if (out.nextCursor == null || typeof out.nextCursor !== "string") break; - cursor = out.nextCursor; + cursor = out.nextCursor ?? null; + if (cursor === null) break; + if (typeof cursor !== "string" || !cursor || seen.has(cursor)) { + throw new CodexProtocolError("thread/turns/list", "invalid or repeated cursor"); + } + seen.add(cursor); } return { threadId: bare, @@ -25848,6 +25690,7 @@ var __webpack_modules__ = { return String(error); } __webpack_require__.d(__webpack_exports__, { + IT: ()=>loadCodexGlobalState, R3: ()=>mapRemoteThreadError, Rg: ()=>RemoteThreadNotLoadedError1 }); @@ -25857,7 +25700,7 @@ var __webpack_modules__ = { const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; const ID_PATTERN = /^[A-Za-z0-9_.:-]{1,128}$/; function isTemporaryDesktopThreadId(threadId) { - return typeof threadId === 'string' && threadId.startsWith(TEMP_THREAD_ID_PREFIX); + return typeof threadId === 'string' && (threadId.startsWith(TEMP_THREAD_ID_PREFIX) || threadId.startsWith('client-new-thread:')); } function normalizeCodexThreadId1(threadId) { if (typeof threadId !== 'string' || !threadId) { @@ -25872,9 +25715,6 @@ var __webpack_modules__ = { } return bare; } - function hasLocalThreadPrefix(threadId) { - return typeof threadId === 'string' && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) && !isTemporaryDesktopThreadId(threadId); - } __webpack_require__.d(__webpack_exports__, { SX: ()=>normalizeCodexThreadId1, vr: ()=>isTemporaryDesktopThreadId @@ -27915,7 +27755,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.", + "description": "Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource", "inputJsonSchema": { "additionalProperties": false, "properties": { diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index e320640..a216462 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -6544,46 +6544,7 @@ var __webpack_modules__ = { modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } - const MODEL_PROVIDER_LIST_METHODS = [ - 'modelProvider/list', - 'model/providers/list', - 'models/providers/list', - 'account/modelProviders/list', - 'config/modelProviders/list', - 'provider/list' - ]; - const REMOTE_ENVIRONMENT_LIST_METHODS = [ - 'remoteEnvironment/list', - 'remote/environments/list', - 'environment/list', - 'remoteControl/hosts/list', - 'remote/hosts/list', - 'hosts/list' - ]; async function discoverModelProviders() { - const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); - try { - for (const method of MODEL_PROVIDER_LIST_METHODS){ - try { - const result = await client.request(method, {}); - const providers = normalizeNamedList(result, [ - 'id', - 'name', - 'provider', - 'modelProvider', - 'slug' - ]); - if (providers.length > 0) { - return { - providers, - source: `app-server:${method}` - }; - } - } catch {} - } - } finally{ - client.close(); - } const providers = new Set(); let cursor; for(let page = 0; page < 20; page++){ @@ -6607,113 +6568,6 @@ var __webpack_modules__ = { source: 'thread/list-distinct' }; } - async function discoverRemoteEnvironments() { - const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); - try { - for (const method of REMOTE_ENVIRONMENT_LIST_METHODS){ - try { - const result = await client.request(method, {}); - const hosts = normalizeHostEntries(result); - if (hosts.length > 0) { - return { - hosts, - source: `app-server:${method}` - }; - } - } catch {} - } - } finally{ - client.close(); - } - return { - hosts: [], - source: null - }; - } - function normalizeNamedList(result, idKeys) { - const raw = listPayload(result); - const out = []; - for (const entry of raw){ - if (typeof entry === 'string' && entry) out.push(entry); - else if (entry && typeof entry === 'object') { - const row = entry; - for (const key of idKeys){ - if (typeof row[key] === 'string' && row[key]) { - out.push(String(row[key])); - break; - } - } - } - } - return [ - ...new Set(out) - ].sort(); - } - function normalizeHostEntries(result) { - const raw = listPayload(result); - const out = []; - for (const entry of raw){ - if (typeof entry === 'string' && entry) { - out.push({ - hostId: entry, - hostName: null - }); - continue; - } - if (!entry || typeof entry !== 'object') continue; - const row = entry; - let hostId = null; - for (const key of [ - 'hostId', - 'id', - 'uuid', - 'environmentId', - 'envId' - ]){ - if (typeof row[key] === 'string' && row[key]) { - hostId = String(row[key]); - break; - } - } - if (!hostId) continue; - let hostName = null; - for (const key of [ - 'hostName', - 'name', - 'displayName', - 'envName', - 'label', - 'title' - ]){ - if (typeof row[key] === 'string' && row[key]) { - hostName = String(row[key]); - break; - } - } - out.push({ - hostId, - hostName - }); - } - return out; - } - function listPayload(result) { - if (Array.isArray(result)) return result; - if (!result || typeof result !== 'object') return []; - const record = result; - for (const key of [ - 'data', - 'providers', - 'modelProviders', - 'hosts', - 'environments', - 'remoteEnvironments', - 'items' - ]){ - if (Array.isArray(record[key])) return record[key]; - } - return []; - } async function appServerReadThread({ threadId, limit = 100, full = false }) { const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); @@ -6838,85 +6692,46 @@ var __webpack_modules__ = { async function listTurnsFull(client, threadId, { limit, full }) { const collected = []; let cursor; - try { - for(let page = 0; page < 40; page++){ - const result = await client.request('thread/turns/list', { + let itemsView = true; + let method = 'thread/turns/list'; + const seen = new Set(); + while(collected.length < limit){ + let result; + try { + result = await client.request(method, { threadId, - limit: 100, - itemsView: 'full', - ...cursor ? { + limit: Math.min(100, limit - collected.length), + sortDirection: full ? 'asc' : 'desc', + ...method === 'thread/turns/list' && itemsView ? { + itemsView: 'full' + } : {}, + ...cursor !== undefined ? { cursor } : {} }); - if (!Array.isArray(result.data)) { - throw new Error(`thread/turns/list missing data array for ${threadId}`); + } catch (error) { + const code = error?.rpc?.code; + if (collected.length === 0 && code === -32602 && itemsView) { + itemsView = false; + continue; } - collected.push(...result.data); - if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; - cursor = result.nextCursor; - if (!full && collected.length >= limit) break; - } - } catch (error) { - if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); - if (collected.length === 0) { - return listTurnsFallback(client, threadId, { - limit, - full - }); - } - throw error; - } - if (collected.length === 0) { - return listTurnsFallback(client, threadId, { - limit, - full - }); - } - return sliceTurns(normalizeTurns(collected), { - limit, - full - }); - } - async function listTurnsFallback(client, threadId, { limit, full }) { - for (const method of [ - 'thread/turns/list', - 'thread/items/list' - ]){ - try { - const collected = []; - let cursor; - for(let page = 0; page < 40; page++){ - const params = { - threadId, - limit: 100, - ...cursor ? { - cursor - } : {} - }; - if (method === 'thread/turns/list') params.itemsView = 'full'; - const result = await client.request(method, params); - if (!Array.isArray(result.data)) break; - collected.push(...result.data); - if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; - cursor = result.nextCursor; - if (!full && collected.length >= limit) break; - } - if (collected.length > 0) { - return sliceTurns(normalizeTurns(collected), { - limit, - full - }); + if (collected.length === 0 && code === -32601 && method === 'thread/turns/list') { + method = 'thread/items/list'; + continue; } - } catch (error) { - if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + throw maybeRemoteThreadError(error, threadId); + } + if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); + collected.push(...result.data); + if (result.nextCursor == null) break; + if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { + throw new Error(`${method} returned an invalid or repeated cursor`); } + seen.add(result.nextCursor); + cursor = result.nextCursor; } - throw new Error(`app-server has no turn history for thread ${threadId}`); - } - function sliceTurns(turns, { limit, full }) { - if (limit <= 0) return turns; - if (full) return turns.slice(0, limit); - return turns.slice(-limit); + const turns = normalizeTurns(collected.slice(0, limit)); + return full ? turns : turns.reverse(); } function normalizeTurns(raw) { const turns = []; @@ -7039,7 +6854,6 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Jf: ()=>appServerReadThread, OI: ()=>appServerListThreads, - OP: ()=>discoverRemoteEnvironments, X: ()=>discoverModelProviders, aI: ()=>appServerSearchThreads, dM: ()=>appServerStatusProbe @@ -7057,6 +6871,7 @@ var __webpack_modules__ = { #version = null; #pageSessionId = null; #mainTargetId = null; + #submittedTurn = null; async connect({ port }) { await this.close(); this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); @@ -7113,25 +6928,40 @@ var __webpack_modules__ = { await (0, _cdp_dom_js__rspack_import_2.s0)(this.#requireSession(), sessionId, { project }); - await delay(300); + await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { + timeoutMs: openTimeoutMs, + threadId: 'new' + }); const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { limit: 20 }); const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); if (temp) temporaryThreadId = temp.threadId; } + const before = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); let conversationId; if (startedNew || threadId && (0, _thread_ids_js__rspack_import_3.vr)(threadId)) { const resolveMs = Math.min(openTimeoutMs, 60000); - conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { - timeoutMs: resolveMs - }); + try { + conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { + timeoutMs: resolveMs + }); + } catch (error) { + throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), { + delivery: 'unknown', + reason: 'conversation-id-unresolved' + }); + } } const durable = (0, _cdp_dom_js__rspack_import_2.X8)(conversationId, threadId); if (!durable) { throw new Error('ChatGPT Desktop send accepted but no durable conversation id was available; ' + 'refusing to return a local:client-new-thread:* id as threadId'); } + this.#submittedTurn = { + threadId: durable, + turnKey: before.lastTurnKey + }; return { threadId: durable, temporaryThreadId, @@ -7145,17 +6975,17 @@ var __webpack_modules__ = { }; } async waitForReply({ threadId, timeoutMs = 120000 }) { + const deadline = Date.now() + timeoutMs; const sessionId = await this.#ensurePageSession(); + const expectedId = threadId && threadId !== 'new' ? (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? undefined : this.#submittedTurn ? (0, _thread_ids_js__rspack_import_3.nn)(this.#submittedTurn.threadId) ?? undefined : undefined; if (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) && threadId !== 'new') { - try { - await this.#openAndWait(sessionId, threadId, 90000); - } catch {} + await this.#openAndWait(sessionId, threadId, Math.min(timeoutMs, 90000)); } - const baseline = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); try { const done = await (0, _cdp_dom_js__rspack_import_2.FG)(this.#requireSession(), sessionId, { - timeoutMs, - baselineFinalCount: baseline.finalAssistantCount + timeoutMs: Math.max(0, deadline - Date.now()), + expectedConversationId: expectedId, + baselineTurnKey: this.#submittedTurn && (!threadId || (0, _thread_ids_js__rspack_import_3.BS)(threadId) === this.#submittedTurn.threadId) ? this.#submittedTurn.turnKey : undefined }); const durable = (0, _cdp_dom_js__rspack_import_2.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_3.BS)(done.conversationId) : null); if (!durable) { @@ -7170,26 +7000,13 @@ var __webpack_modules__ = { delivery: 'replied' }; } catch (error) { - const last = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); - const durable = (0, _cdp_dom_js__rspack_import_2.X8)(last.conversationId, threadId); - if (last.reply && durable) { - return { - threadId: durable, - conversationId: last.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, - reply: last.reply, - backend: 'cdp', - experimental: false, - delivery: 'replied' - }; - } + if (!(error instanceof _cdp_dom_js__rspack_import_2.aw)) throw error; return { - threadId: durable ?? (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) ? threadId : 'unknown'), - conversationId: last.conversationId || undefined, - reply: last.reply, + threadId: threadId ?? 'unknown', + reply: '', backend: 'cdp', experimental: false, - delivery: last.reply ? 'replied' : 'timeout', - ...error instanceof Error ? {} : {} + delivery: 'timeout' }; } } @@ -7246,7 +7063,8 @@ var __webpack_modules__ = { async #openAndWait(sessionId, threadId, openTimeoutMs) { await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { - timeoutMs: openTimeoutMs + timeoutMs: openTimeoutMs, + threadId }); } async #attachMainWindow() { @@ -7277,9 +7095,6 @@ var __webpack_modules__ = { return this.#session; } } - function delay(ms) { - return new Promise((resolve)=>setTimeout(resolve, ms)); - } __webpack_require__.d(__webpack_exports__, { a: ()=>CdpChatGptDesktopAdapter }); @@ -7454,6 +7269,7 @@ var __webpack_modules__ = { preferred.click(); return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; } + return { ok: false, error: 'project-not-found' }; } const buttons = Array.from(document.querySelectorAll('button')); const fallback = buttons.find((btn) => (btn.textContent || '').trim() === 'New chat'); @@ -7476,6 +7292,8 @@ var __webpack_modules__ = { const FOCUS_COMPOSER_EXPRESSION = `(() => { const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); if (!composer) return { ok: false, error: 'composer-not-found' }; + if ((composer.textContent || '').trim()) return { ok: false, error: 'composer-has-draft' }; + if (document.querySelector(${JSON.stringify(STOP_BUTTON_SELECTOR)})) return { ok: false, error: 'reply-in-progress' }; composer.focus(); return { ok: true }; })()`; @@ -7503,6 +7321,7 @@ var __webpack_modules__ = { conversationId, reply, lastTurnKey, + finalTurnKey: lastFinal?.closest(${JSON.stringify(SELECTORS.turn)})?.getAttribute(${JSON.stringify(ATTR.turnKey)}) || '', }; })()`; const CONVERSATION_ID_EXPRESSION = `(() => { @@ -7587,13 +7406,23 @@ var __webpack_modules__ = { throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); } } - async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS } = {}) { + async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS, threadId } = {}) { const deadline = Date.now() + timeoutMs; while(Date.now() < deadline){ const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { sessionId }); - if (gone) return; + if (gone) { + const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; + if (!threadId) return; + if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + const rows = await listThreadsFromDom(session, sessionId, { + limit: 200 + }); + const selected = rows.find((row)=>row.selected); + if (!current && (!selected || (0, _codex_thread_id_js__rspack_import_0.vr)(selected.threadId))) return; + } else if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; + } await delay(250); } throw new Error(`ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); @@ -7614,7 +7443,7 @@ var __webpack_modules__ = { sessionId }); if (!focused?.ok) { - throw new Error('ChatGPT Desktop composer not found ([data-codex-composer=true])'); + throw new Error(`ChatGPT Desktop composer unavailable: ${focused?.error || 'not found'}`); } } async function submitComposerWithEnter(session, sessionId) { @@ -7631,12 +7460,6 @@ var __webpack_modules__ = { }, { sessionId }); - await session.send('Input.dispatchKeyEvent', { - type: 'char', - ...base - }, { - sessionId - }); await session.send('Input.dispatchKeyEvent', { type: 'keyUp', ...base @@ -7644,17 +7467,6 @@ var __webpack_modules__ = { sessionId }); } - async function submitComposerWithButton(session, sessionId) { - const result = await session.evaluate(`(() => { - const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); - if (!btn || btn.disabled) return { ok: false }; - btn.click(); - return { ok: true }; - })()`, { - sessionId - }); - return Boolean(result?.ok); - } async function sendMessageInDom(session, sessionId, text) { await focusComposer(session, sessionId); await session.send('Input.insertText', { @@ -7662,22 +7474,28 @@ var __webpack_modules__ = { }, { sessionId }); - await submitComposerWithEnter(session, sessionId); - const sendStillVisible = await session.evaluate(`(() => { - const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); - return Boolean(btn && !btn.disabled); - })()`, { - sessionId - }); - if (sendStillVisible) { - const clicked = await submitComposerWithButton(session, sessionId); - if (clicked) return { - sentVia: 'button' - }; + try { + await submitComposerWithEnter(session, sessionId); + const deadline = Date.now() + 3000; + while(Date.now() < deadline){ + const cleared = await session.evaluate(`(() => { + const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + return Boolean(composer && !(composer.textContent || '').trim()); + })()`, { + sessionId + }); + if (cleared) return { + sentVia: 'enter' + }; + await delay(100); + } + throw new Error('Desktop composer did not acknowledge submission'); + } catch (error) { + throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), { + delivery: 'unknown', + reason: 'submission-unconfirmed' + }); } - return { - sentVia: 'enter' - }; } async function readReplyState(session, sessionId) { const state = await session.evaluate(REPLY_STATE_EXPRESSION, { @@ -7688,7 +7506,8 @@ var __webpack_modules__ = { finalAssistantCount: Number(state?.finalAssistantCount ?? 0), conversationId: String(state?.conversationId ?? ''), reply: String(state?.reply ?? ''), - lastTurnKey: String(state?.lastTurnKey ?? '') + lastTurnKey: String(state?.lastTurnKey ?? ''), + finalTurnKey: String(state?.finalTurnKey ?? '') }; } async function readConversationIdFromDom(session, sessionId) { @@ -7717,14 +7536,21 @@ var __webpack_modules__ = { } return null; } - async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0 } = {}) { + class ReplyTimeoutError extends Error { + } + async function waitForReplyDone(session, sessionId, { timeoutMs = 120000, baselineFinalCount = 0, expectedConversationId, baselineTurnKey } = {}) { const deadline = Date.now() + timeoutMs; let sawStop = false; const started = Date.now(); while(Date.now() < deadline){ const state = await readReplyState(session, sessionId); if (state.stopVisible) sawStop = true; - const hasNewFinal = state.finalAssistantCount > baselineFinalCount && Boolean(state.reply); + expectedConversationId ??= state.conversationId || undefined; + if (expectedConversationId && state.conversationId && durableThreadKey(state.conversationId) !== durableThreadKey(expectedConversationId)) { + throw new Error('ChatGPT Desktop selected conversation changed while waiting'); + } + const latestIsFinal = Boolean(state.finalTurnKey) && state.finalTurnKey === state.lastTurnKey; + const hasNewFinal = (state.finalAssistantCount > baselineFinalCount || sawStop) && Boolean(state.reply) && latestIsFinal && (!baselineTurnKey || state.lastTurnKey !== baselineTurnKey); if (!state.stopVisible && hasNewFinal && (sawStop || Date.now() - started > 1500)) { return { reply: state.reply, @@ -7733,14 +7559,7 @@ var __webpack_modules__ = { } await delay(200); } - const last = await readReplyState(session, sessionId); - if (!last.stopVisible && last.finalAssistantCount > baselineFinalCount && last.reply) { - return { - reply: last.reply, - conversationId: last.conversationId - }; - } - throw new Error(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); + throw new ReplyTimeoutError(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); } function normalizeTurn(raw) { const role = raw.role === 'user' || raw.role === 'status' || raw.role === 'assistant' ? raw.role : raw.assistantText ? 'assistant' : raw.userText ? 'user' : 'assistant'; @@ -7817,6 +7636,7 @@ var __webpack_modules__ = { X8: ()=>resolveDurableThreadId, YX: ()=>readReplyState, Zx: ()=>waitForLoadingTaskGone, + aw: ()=>ReplyTimeoutError, lh: ()=>sendMessageInDom, s0: ()=>startNewChatInDom, z9: ()=>waitForConversationId @@ -7847,7 +7667,11 @@ var __webpack_modules__ = { let response; try { response = await fetch(`${base}/json/version`, { - signal + signal: signal ? AbortSignal.any([ + signal, + AbortSignal.timeout(5000) + ]) : AbortSignal.timeout(5000), + redirect: 'error' }); } catch (error) { throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/version: ` + (error instanceof Error ? error.message : String(error))); @@ -7855,14 +7679,22 @@ var __webpack_modules__ = { if (!response.ok) { throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP /json/version returned HTTP ${response.status}`); } - return await response.json(); + const version = await response.json(); + if (typeof version.webSocketDebuggerUrl === 'string') { + (0, _loopback_js__rspack_import_1.jv)(version.webSocketDebuggerUrl); + } + return version; } static async fetchJsonList(port, { signal } = {}) { const base = (0, _loopback_js__rspack_import_1.NJ)(port); let response; try { response = await fetch(`${base}/json/list`, { - signal + signal: signal ? AbortSignal.any([ + signal, + AbortSignal.timeout(5000) + ]) : AbortSignal.timeout(5000), + redirect: 'error' }); } catch (error) { throw new _errors_js__rspack_import_0.sO(`ChatGPT Desktop CDP not reachable at ${base}/json/list: ` + (error instanceof Error ? error.message : String(error))); @@ -7885,35 +7717,43 @@ var __webpack_modules__ = { throw new _errors_js__rspack_import_0.sO('CDP /json/version omitted webSocketDebuggerUrl'); } const url = (0, _loopback_js__rspack_import_1.jv)(rawUrl); - const parsed = new URL(url); - (0, _loopback_js__rspack_import_1.tb)(parsed.hostname); + signal?.throwIfAborted(); await new Promise((resolve, reject)=>{ const ws = new WebSocket(url); this.#ws = ws; + const cleanup = ()=>{ + clearTimeout(timer); + signal?.removeEventListener('abort', onAbort); + }; const onAbort = ()=>{ + cleanup(); ws.close(); - reject(new Error('CDP connect aborted')); + reject(new _errors_js__rspack_import_0.sO('CDP connect aborted or timed out')); }; + const timer = setTimeout(onAbort, 5000); signal?.addEventListener('abort', onAbort, { once: true }); ws.addEventListener('open', ()=>{ - signal?.removeEventListener('abort', onAbort); + cleanup(); resolve(); }, { once: true }); ws.addEventListener('error', ()=>{ - signal?.removeEventListener('abort', onAbort); + cleanup(); reject(new _errors_js__rspack_import_0.sO(`CDP WebSocket failed for ${url}`)); }, { once: true }); ws.addEventListener('message', (event)=>this.#onMessage(event.data)); ws.addEventListener('close', ()=>{ + cleanup(); + reject(new _errors_js__rspack_import_0.sO('CDP WebSocket closed before connecting')); this.#closed = true; for (const [, pending] of this.#pending){ - pending.reject(new Error('CDP WebSocket closed')); + clearTimeout(pending.timer); + pending.reject(new _errors_js__rspack_import_0.sO('CDP WebSocket closed')); } this.#pending.clear(); }); @@ -7933,11 +7773,22 @@ var __webpack_modules__ = { if (params !== undefined) payload.params = params; if (sessionId !== undefined) payload.sessionId = sessionId; return await new Promise((resolve, reject)=>{ + const timer = setTimeout(()=>{ + this.#pending.delete(id); + reject(new _errors_js__rspack_import_0.sO(`CDP ${method} timed out`)); + }, 10000); this.#pending.set(id, { + timer, resolve: (value)=>resolve(value), reject }); - this.#ws.send(JSON.stringify(payload)); + try { + this.#ws.send(JSON.stringify(payload)); + } catch (error) { + clearTimeout(timer); + this.#pending.delete(id); + reject(error); + } }); } async evaluate(expression, { sessionId, awaitPromise = true } = {}) { @@ -7956,6 +7807,11 @@ var __webpack_modules__ = { } close() { this.#closed = true; + for (const pending of this.#pending.values()){ + clearTimeout(pending.timer); + pending.reject(new _errors_js__rspack_import_0.sO('CDP session closed')); + } + this.#pending.clear(); this.#ws?.close(); this.#ws = null; } @@ -7966,10 +7822,11 @@ var __webpack_modules__ = { } catch { return; } - if (typeof message.id !== 'number') return; + if (!message || typeof message !== 'object' || typeof message.id !== 'number') return; const pending = this.#pending.get(message.id); if (!pending) return; this.#pending.delete(message.id); + clearTimeout(pending.timer); if (message.error) { pending.reject(new Error(message.error.message || 'CDP error')); return; @@ -8010,15 +7867,9 @@ var __webpack_modules__ = { this.name = 'CdpUnreachableError'; } } - class RemoteThreadNotLoadedError1 extends _codex_remote_control_js__rspack_import_0.Rg { - constructor(threadId, hostId = null, hostName = null){ - super(threadId, hostId, hostName); - this.name = 'RemoteThreadNotLoadedError'; - } - } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, - Rg: ()=>RemoteThreadNotLoadedError1, + Rg: ()=>_codex_remote_control_js__rspack_import_0.Rg, c$: ()=>CdpHostRejectedError, sO: ()=>CdpUnreachableError }); @@ -8037,8 +7888,7 @@ var __webpack_modules__ = { statusProbe: _app_server_fallback_js__rspack_import_1.dM, listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, listHosts: _remote_threads_js__rspack_import_4.Kl, - discoverModelProviders: _app_server_fallback_js__rspack_import_1.X, - discoverRemoteEnvironments: _app_server_fallback_js__rspack_import_1.OP + discoverModelProviders: _app_server_fallback_js__rspack_import_1.X }; class ChatGptDesktopFacade { #cdp; @@ -8094,19 +7944,25 @@ var __webpack_modules__ = { cdpError = error; } } + const remotes = this.#listRemotes(); let base = null; if (appList && cdpList) base = mergeThreadLists(appList, cdpList); else if (appList) base = appList; else if (cdpList) base = cdpList; + else if (remotes.length) base = { + backend: 'app-server', + limit, + threads: [] + }; else if (cdpError) throw cdpError; else if (appError) throw appError; else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); return finalizeThreadList(base, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, - remotes: this.#listRemotes() + remotes }); } async listHosts() { @@ -8147,30 +8003,7 @@ var __webpack_modules__ = { }); } } - let hostsSource = 'remote-thread-summaries-v3+local'; - try { - const discoverEnvs = this.#fallbacks.discoverRemoteEnvironments ?? _app_server_fallback_js__rspack_import_1.OP; - const appHosts = await discoverEnvs(); - if (appHosts.source && appHosts.hosts.length > 0) { - for (const host of appHosts.hosts){ - const existing = byId.get(host.hostId); - if (existing) { - byId.set(host.hostId, { - ...existing, - hostName: existing.hostName ?? host.hostName - }); - } else { - byId.set(host.hostId, { - hostId: host.hostId, - hostName: host.hostName, - location: 'remote', - threadCount: 0 - }); - } - } - hostsSource = `${appHosts.source}+remote-thread-summaries-v3+local`; - } - } catch {} + const hostsSource = 'remote-thread-summaries-v3+local'; const remoteCounts = new Map(); for (const thread of remotes){ remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); @@ -8203,6 +8036,12 @@ var __webpack_modules__ = { ].sort(); modelProvidersSource = 'remote-summaries-distinct'; } + modelProviders = [ + ...new Set([ + ...modelProviders, + ...remotes.map((thread)=>thread.modelProvider).filter((value)=>Boolean(value)) + ]) + ].sort(); return { hosts: withCounts, hostsSource, @@ -8228,7 +8067,7 @@ var __webpack_modules__ = { const withRemotes = finalizeThreadList(base, { limit: 10000, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, remotes: this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); @@ -8240,7 +8079,7 @@ var __webpack_modules__ = { return finalizeThreadList(filtered, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: [] }); @@ -8248,19 +8087,23 @@ var __webpack_modules__ = { const cdpList = await this.#tryCdpList({ limit }); - if (!cdpList) throw appError; + const remotes = this.#listRemotes(); + if (!cdpList && !remotes.length) throw appError; const needle = options.query.trim().toLowerCase(); const filtered = { - ...cdpList, + ...cdpList ?? { + backend: 'app-server', + limit + }, query: options.query, - threads: cdpList.threads.filter((thread)=>threadMatchesQuery(thread, needle)) + threads: (cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) }; return finalizeThreadList(filtered, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, - remotes: this.#listRemotes() + remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) }); } } @@ -8288,7 +8131,7 @@ var __webpack_modules__ = { return this.#cdp.readThread({ ...options, limit, - full: full || true + full }); } } @@ -8393,12 +8236,7 @@ var __webpack_modules__ = { }); for (const thread of cdpList.threads){ if (merged.some((row)=>(0, _thread_ids_js__rspack_import_5.LV)(row.threadId, thread.threadId))) continue; - merged.push({ - ...thread, - location: thread.location ?? 'local', - hostId: thread.hostId ?? null, - hostName: thread.hostName ?? null - }); + merged.push(thread); } return { backend: appList.backend, @@ -8411,7 +8249,20 @@ var __webpack_modules__ = { }; } function finalizeThreadList(base, { limit, host = 'all', modelProvider, groupBy, remotes }) { + const remoteById = new Map(remotes.map((thread)=>[ + (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId, + thread + ])); const locals = base.threads.map((thread)=>{ + const remote = remoteById.get((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId); + if (remote && thread.location === undefined) { + return { + ...thread, + ...remote, + selected: thread.selected, + pinned: thread.pinned || remote.pinned + }; + } const location = thread.location ?? 'local'; return { ...thread, @@ -8509,9 +8360,6 @@ var __webpack_modules__ = { } function modelProviderMatches(thread, modelProvider) { if (!modelProvider) return true; - if (!thread.modelProvider) { - return thread.location === 'remote'; - } return thread.modelProvider === modelProvider; } function threadMatchesQuery(thread, needle) { @@ -8578,6 +8426,7 @@ var __webpack_modules__ = { throw new _errors_js__rspack_import_0.c$(String(raw)); } assertLoopbackHostname(url.hostname); + if (url.username || url.password || url.hash) throw new _errors_js__rspack_import_0.c$(raw); if (url.protocol !== 'ws:' && url.protocol !== 'wss:') { throw new Error(`Expected ws(s) debugger URL, got ${url.protocol}`); } @@ -8594,7 +8443,7 @@ var __webpack_modules__ = { } const raw = (env.CHATGPT_DESKTOP_CDP_PORT || '').trim(); if (!raw) return DEFAULT_CDP_PORT; - const port = Number.parseInt(raw, 10); + const port = /^\d+$/.test(raw) ? Number(raw) : NaN; if (!Number.isInteger(port) || port < 1 || port > 65535) { throw new RangeError('CHATGPT_DESKTOP_CDP_PORT must be an integer 1-65535'); } @@ -8603,37 +8452,15 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { L0: ()=>resolveCdpPort, NJ: ()=>cdpHttpBase, - jv: ()=>forceLoopbackWebSocketUrl, - tb: ()=>assertLoopbackHostname + jv: ()=>forceLoopbackWebSocketUrl }); }, "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var node_fs__rspack_import_0 = __webpack_require__("node:fs"); - var node_os__rspack_import_1 = __webpack_require__("node:os"); - var node_path__rspack_import_2 = __webpack_require__("node:path"); - var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const REMOTE_SUMMARY_KEY = /^remote-thread-summaries-v3:(.+)$/; - function codexGlobalStatePath(env = process.env) { - const home = env.CODEX_HOME || (0, node_path__rspack_import_2.join)((0, node_os__rspack_import_1.homedir)(), '.codex'); - return (0, node_path__rspack_import_2.join)(home, '.codex-global-state.json'); - } - function loadCodexGlobalState(env = process.env) { - let raw; - try { - raw = (0, node_fs__rspack_import_0.readFileSync)(codexGlobalStatePath(env), 'utf8'); - } catch { - return null; - } - try { - const data = JSON.parse(raw); - if (!data || typeof data !== 'object' || Array.isArray(data)) return null; - return data; - } catch { - return null; - } - } function listRemoteThreadsFromState(env = process.env) { - const data = loadCodexGlobalState(env); + const data = (0, _codex_remote_control_js__rspack_import_0.IT)(env); if (!data) return []; const hostNames = collectHostNames(data); const out = []; @@ -8651,7 +8478,7 @@ var __webpack_modules__ = { pinnedIds }); if (!mapped) continue; - const bare = (0, _thread_ids_js__rspack_import_3.nn)(mapped.threadId) ?? mapped.threadId; + const bare = (0, _thread_ids_js__rspack_import_1.nn)(mapped.threadId) ?? mapped.threadId; const dedupe = `${hostId}:${bare}`; if (seen.has(dedupe)) continue; seen.add(dedupe); @@ -8661,10 +8488,10 @@ var __webpack_modules__ = { return out; } function findRemoteThread(threadId, env = process.env) { - const bare = (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? threadId; + const bare = (0, _thread_ids_js__rspack_import_1.nn)(threadId) ?? threadId; if (!bare) return null; for (const thread of listRemoteThreadsFromState(env)){ - const id = (0, _thread_ids_js__rspack_import_3.nn)(thread.threadId) ?? thread.threadId; + const id = (0, _thread_ids_js__rspack_import_1.nn)(thread.threadId) ?? thread.threadId; if (id === bare) { return { hostId: thread.hostId, @@ -8687,7 +8514,7 @@ var __webpack_modules__ = { location: 'local', threadCount: localThreadCount }); - const data = loadCodexGlobalState(env); + const data = (0, _codex_remote_control_js__rspack_import_0.IT)(env); if (data) { const hostNames = collectHostNames(data); for (const key of Object.keys(data)){ @@ -8875,7 +8702,7 @@ var __webpack_modules__ = { function mapRemoteEntry(entry, { hostId, hostName, pinnedIds }) { if (typeof entry === 'string' && entry) { return { - threadId: (0, _thread_ids_js__rspack_import_3.BS)(entry), + threadId: (0, _thread_ids_js__rspack_import_1.BS)(entry), title: entry, pinned: pinnedIds.has(entry), selected: false, @@ -8949,7 +8776,7 @@ var __webpack_modules__ = { ]) || sectionName; const pinned = pinnedIds.has(id) || row.pinned === true || sectionId === 'Pinned' || sectionName === 'Pinned'; return { - threadId: (0, _thread_ids_js__rspack_import_3.BS)(id), + threadId: (0, _thread_ids_js__rspack_import_1.BS)(id), title, pinned, selected: false, @@ -9059,7 +8886,7 @@ var __webpack_modules__ = { const sendSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), - text: zod__rspack_import_4.YjP().min(1).max(100000), + text: zod__rspack_import_4.YjP().trim().min(1).max(100000), project: zod__rspack_import_4.YjP().min(1).max(256).optional(), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); @@ -9074,19 +8901,27 @@ var __webpack_modules__ = { zod__rspack_import_4.euz(1) ]) }).catchall(zod__rspack_import_4.Pq9()); + let operationQueue = Promise.resolve(); async function withAdapter(port, run) { - const adapter = (0, _facade_js__rspack_import_2.PP)(); - const resolved = (0, _loopback_js__rspack_import_3.L0)(process.env, port); - try { - await adapter.connect({ - port: resolved - }); - } catch {} - return run(adapter); + const operation = operationQueue.then(async ()=>{ + const adapter = (0, _facade_js__rspack_import_2.PP)(); + const resolved = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + try { + try { + await adapter.connect({ + port: resolved + }); + } catch {} + return await run(adapter); + } finally{ + await adapter.close(); + } + }); + operationQueue = operation.catch(()=>{}); + return operation; } function asResult(value) { - const cleaned = Object.fromEntries(Object.entries(value).filter(([, entry])=>entry !== undefined)); - return resultSchema.parse(cleaned); + return resultSchema.parse(JSON.parse(JSON.stringify(value))); } function mapError(error) { if (error instanceof _errors_js__rspack_import_1.EH) { @@ -9204,6 +9039,7 @@ var __webpack_modules__ = { } async function sendOperation(input) { try { + input = sendSchema.parse(input); const out = await withAdapter(input.port, (adapter)=>adapter.sendMessage({ threadId: input.threadId, text: input.text, @@ -9236,7 +9072,7 @@ var __webpack_modules__ = { if (result.error) return String(result.error); if (result.reachable === true) { const backend = result.appServerFallback && typeof result.appServerFallback === 'object' ? ` cdp + app-server probe` : ''; - return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; + return result.message ? String(result.message) : `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); if (Array.isArray(result.hosts)) { @@ -9407,11 +9243,11 @@ var __webpack_modules__ = { }; const sendFields = { ...observationFields, - correlationId: id.optional(), + correlationId: bareId.optional(), envelope: zod__rspack_import_3.zMY().optional(), hop: zod__rspack_import_3.aig().int().min(0).optional(), - replyTo: id.optional(), - expectedTurnId: id.optional(), + replyTo: bareId.optional(), + expectedTurnId: bareId.optional(), whenBusy: zod__rspack_import_3.k5n([ 'reject', 'queue', @@ -9426,8 +9262,8 @@ var __webpack_modules__ = { }).strict(); const waitSchema = zod__rspack_import_3.Ikc({ ...observationFields, - turnId: id, - messageId: id.optional(), + turnId: bareId, + messageId: bareId.optional(), maxOutputBytes: zod__rspack_import_3.aig().int().min(1).max(4194304).optional() }).strict(); const watchSchema = zod__rspack_import_3.Ikc({ @@ -9920,7 +9756,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list hosts', - description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.', + description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource', annotations: { readOnlyHint: true }, @@ -59427,7 +59263,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.", + "description": "Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -61852,6 +61688,7 @@ var __webpack_modules__ = { } const turns = []; let cursor; + const seen = new Set(); for(let page = 0; page < 40 && turns.length < limit; page++){ let out; try { @@ -61859,6 +61696,7 @@ var __webpack_modules__ = { threadId: bare, limit: Math.min(100, limit - turns.length), itemsView: "full", + sortDirection: "desc", ...cursor !== undefined ? { cursor } : {} @@ -61872,8 +61710,12 @@ var __webpack_modules__ = { throw new CodexProtocolError("thread/turns/list", "missing `data` array"); } for (const row of out.data)turns.push(row); - if (out.nextCursor == null || typeof out.nextCursor !== "string") break; - cursor = out.nextCursor; + cursor = out.nextCursor ?? null; + if (cursor === null) break; + if (typeof cursor !== "string" || !cursor || seen.has(cursor)) { + throw new CodexProtocolError("thread/turns/list", "invalid or repeated cursor"); + } + seen.add(cursor); } return { threadId: bare, @@ -62888,6 +62730,7 @@ var __webpack_modules__ = { return String(error); } __webpack_require__.d(__webpack_exports__, { + IT: ()=>loadCodexGlobalState, R3: ()=>mapRemoteThreadError, Rg: ()=>RemoteThreadNotLoadedError1 }); @@ -62897,7 +62740,7 @@ var __webpack_modules__ = { const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; const ID_PATTERN = /^[A-Za-z0-9_.:-]{1,128}$/; function isTemporaryDesktopThreadId(threadId) { - return typeof threadId === 'string' && threadId.startsWith(TEMP_THREAD_ID_PREFIX); + return typeof threadId === 'string' && (threadId.startsWith(TEMP_THREAD_ID_PREFIX) || threadId.startsWith('client-new-thread:')); } function normalizeCodexThreadId1(threadId) { if (typeof threadId !== 'string' || !threadId) { @@ -62912,9 +62755,6 @@ var __webpack_modules__ = { } return bare; } - function hasLocalThreadPrefix(threadId) { - return typeof threadId === 'string' && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) && !isTemporaryDesktopThreadId(threadId); - } __webpack_require__.d(__webpack_exports__, { SX: ()=>normalizeCodexThreadId1, vr: ()=>isTemporaryDesktopThreadId diff --git a/artifact/scripts/gbot-relay.mjs b/artifact/scripts/gbot-relay.mjs index ffb4eef..f9e86d4 100644 --- a/artifact/scripts/gbot-relay.mjs +++ b/artifact/scripts/gbot-relay.mjs @@ -23265,6 +23265,7 @@ var __webpack_modules__ = { } const turns = []; let cursor; + const seen = new Set(); for(let page = 0; page < 40 && turns.length < limit; page++){ let out; try { @@ -23272,6 +23273,7 @@ var __webpack_modules__ = { threadId: bare, limit: Math.min(100, limit - turns.length), itemsView: "full", + sortDirection: "desc", ...cursor !== undefined ? { cursor } : {} @@ -23285,8 +23287,12 @@ var __webpack_modules__ = { throw new CodexProtocolError("thread/turns/list", "missing `data` array"); } for (const row of out.data)turns.push(row); - if (out.nextCursor == null || typeof out.nextCursor !== "string") break; - cursor = out.nextCursor; + cursor = out.nextCursor ?? null; + if (cursor === null) break; + if (typeof cursor !== "string" || !cursor || seen.has(cursor)) { + throw new CodexProtocolError("thread/turns/list", "invalid or repeated cursor"); + } + seen.add(cursor); } return { threadId: bare, @@ -24307,7 +24313,7 @@ var __webpack_modules__ = { const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; const ID_PATTERN = /^[A-Za-z0-9_.:-]{1,128}$/; function isTemporaryDesktopThreadId(threadId) { - return typeof threadId === 'string' && threadId.startsWith(TEMP_THREAD_ID_PREFIX); + return typeof threadId === 'string' && (threadId.startsWith(TEMP_THREAD_ID_PREFIX) || threadId.startsWith('client-new-thread:')); } function normalizeCodexThreadId1(threadId) { if (typeof threadId !== 'string' || !threadId) { @@ -24322,9 +24328,6 @@ var __webpack_modules__ = { } return bare; } - function hasLocalThreadPrefix(threadId) { - return typeof threadId === 'string' && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) && !isTemporaryDesktopThreadId(threadId); - } __webpack_require__.d(__webpack_exports__, { SX: ()=>normalizeCodexThreadId1 }); diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index d3dd6a7..7b926a3 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -81,7 +81,9 @@ DOM (tool calls, reasoning, timing, and sometimes more turns). 2. `thread/read` for **metadata only** (`includeTurns` is deprecated for paginated threads) 3. Page history with `thread/turns/list` (`itemsView: "full"`, `cursor` / - `nextCursor`); `thread/items/list` is a fallback + `nextCursor`); `thread/items/list` is a fallback only for unsupported RPCs. + Recent reads request descending pages and return chronological turns; + `full` reads request ascending pages, bounded by `limit`. Empty history is valid. 4. **Do not** `thread/resume` for reads — resume attaches a live session `thread/list` filters to the current model provider by default. Pass @@ -115,12 +117,11 @@ Hosts are discovered dynamically — do not hardcode them: 1. Always include `local` 2. Every `remote-thread-summaries-v3:` key in `~/.codex/.codex-global-state.json`, with friendly names and thread counts -3. If app-server exposes a remote-environment list method, merge those hosts - too (`hostsSource` names what was used) -`modelProviders` on the same result: prefer a dedicated app-server list method -when present; otherwise distinct `modelProvider` values from `thread/list` -(`modelProviders: []`). `modelProvidersSource` names the path used. +`modelProviders` combines distinct `modelProvider` values from `thread/list` +(`modelProviders: []`) and remote summaries. `modelProvidersSource` names the +local discovery path; if unavailable, remote summaries still contribute. +Explicit provider filters exclude rows whose provider is unknown. ### Remote-control threads @@ -138,7 +139,7 @@ skipped. | Operation | CDP | App-server | | --- | --- | --- | | `status` | `/json/version` + attach | daemon probe | -| `list_hosts` | — | global-state keys (+ optional remote-env method) + provider discovery | +| `list_hosts` | — | global-state keys + thread inventory provider discovery | | `list_threads` | merge selected / UI overlay | primary inventory + remote summaries | | `search_threads` | merge selected when connected | primary (list + filter, includes remotes) | | `read_thread` | DOM harvest / wheel **fallback only** (local) | primary; remote → typed error + host hint | @@ -158,7 +159,7 @@ use it only as a cheap status hint. All selectors live in `src/core/chatgpt-desktop/cdp-dom.ts`: - Composer: `[data-codex-composer=true][contenteditable=true]` — `focus()` then `Input.insertText` -- Submit: Enter via `Input.dispatchKeyEvent` (rawKeyDown/char/keyUp), Send button fallback +- Submit: Enter via `Input.dispatchKeyEvent` (rawKeyDown/keyUp), waits for the composer to clear without resubmitting - Reply done: `main button[aria-label="Stop"]` gone + new `[data-local-conversation-final-assistant=true]` - Reply text: last turn’s `[data-local-conversation-final-assistant=true] [data-markdown-text-style=assistant-message]` - New chat: `button[aria-label="Start new chat in "]` (preferred) or sidebar “New chat” @@ -173,3 +174,26 @@ All selectors live in `src/core/chatgpt-desktop/cdp-dom.ts`: List / search / read reuse the existing client in `codex-bridge.js` (`listCodexThreads`, `openCodexSession`, `codexStatus`) — no duplicated JSON-RPC stack. Send / new-thread-in-project / wait-for-reply stay on CDP. + +## Operation boundaries + +CDP HTTP discovery rejects redirects and non-loopback debugger URLs. Discovery +and connection attempts time out after 5 seconds; individual CDP requests after +10 seconds. CLI/MCP calls close their connection on completion and serialize +access to the shared Desktop composer within one process. + +Opening a thread waits for its conversation annotation as well as the absence +of “Loading task…”, so a still-rendered previous chat is not used. Reply waits +require the latest turn to have a final reply with Stop absent. A timeout is +reported as a timeout, never as a successful partial reply. Changing the +selected conversation during a wait fails the operation. A requested project +must exist; it does not silently fall back to an unrelated new chat. + +Separate CLI processes and manual Desktop interaction can still race with UI +operations; avoid driving the same window concurrently. DOM selectors and the +remote-summary file format are app-internal and can change between releases. + +Sends refuse an existing composer draft or active reply. Once Enter is dispatched, +a missing acknowledgment or durable conversation ID reports unknown delivery; +it must not be retried blindly. A send/wait pair in the same MCP process tracks +the pre-submit turn key to avoid returning the previous answer. diff --git a/src/cli/chatgpt-desktop/hosts.tsx b/src/cli/chatgpt-desktop/hosts.tsx index ba4d5ee..030e14b 100644 --- a/src/cli/chatgpt-desktop/hosts.tsx +++ b/src/cli/chatgpt-desktop/hosts.tsx @@ -10,7 +10,7 @@ import { export const config = { description: - 'Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; merges app-server remote-environment methods when present. Providers from app-server list or distinct thread/list values.', + 'Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.', exitCode: 'result', inputJsonSchema: { additionalProperties: false, diff --git a/src/cli/chatgpt-desktop/send.tsx b/src/cli/chatgpt-desktop/send.tsx index 669f118..670f962 100644 --- a/src/cli/chatgpt-desktop/send.tsx +++ b/src/cli/chatgpt-desktop/send.tsx @@ -25,7 +25,7 @@ export const config = { required: ['text'], type: 'object', }, - render: { maxElapsedMs: 180000 }, + render: { maxElapsedMs: 660000 }, } satisfies CliRouteConfig; export const inputSchema = z diff --git a/src/core/chatgpt-desktop/app-server-fallback.ts b/src/core/chatgpt-desktop/app-server-fallback.ts index c5ffdd2..aa79273 100644 --- a/src/core/chatgpt-desktop/app-server-fallback.ts +++ b/src/core/chatgpt-desktop/app-server-fallback.ts @@ -84,68 +84,13 @@ export async function appServerSearchThreads({ }; } -/** Candidate app-server RPCs that might list configured model providers. */ -const MODEL_PROVIDER_LIST_METHODS = [ - 'modelProvider/list', - 'model/providers/list', - 'models/providers/list', - 'account/modelProviders/list', - 'config/modelProviders/list', - 'provider/list', -] as const; - -/** Candidate app-server RPCs that might list remote-control environments/hosts. */ -const REMOTE_ENVIRONMENT_LIST_METHODS = [ - 'remoteEnvironment/list', - 'remote/environments/list', - 'environment/list', - 'remoteControl/hosts/list', - 'remote/hosts/list', - 'hosts/list', -] as const; - export type ModelProvidersDiscovery = { readonly providers: readonly string[]; - /** Which discovery path produced the list. */ - readonly source: - | `app-server:${(typeof MODEL_PROVIDER_LIST_METHODS)[number]}` - | 'thread/list-distinct'; + readonly source: 'thread/list-distinct'; }; -export type RemoteEnvironmentsDiscovery = { - readonly hosts: readonly { hostId: string; hostName: string | null }[]; - readonly source: `app-server:${(typeof REMOTE_ENVIRONMENT_LIST_METHODS)[number]}` | null; -}; - -/** - * Discover configured model providers. Prefers a dedicated app-server list - * method when present; otherwise distinct `modelProvider` values from - * `thread/list` (`modelProviders: []`). - */ +/** Discover provider IDs from the supported inventory, without guessing RPCs. */ export async function discoverModelProviders(): Promise { - const { client } = await openCodexSession(); - try { - for (const method of MODEL_PROVIDER_LIST_METHODS) { - try { - const result = await client.request(method, {}) as unknown; - const providers = normalizeNamedList(result, [ - 'id', - 'name', - 'provider', - 'modelProvider', - 'slug', - ]); - if (providers.length > 0) { - return { providers, source: `app-server:${method}` }; - } - } catch { - // Method missing or rejected — try the next candidate. - } - } - } finally { - client.close(); - } - const providers = new Set(); let cursor: string | undefined; for (let page = 0; page < 20; page++) { @@ -164,99 +109,6 @@ export async function discoverModelProviders(): Promise }; } -/** - * Probe app-server for a remote-environment / hosts list method. - * Returns null source when no such method exists (callers fall back to - * `remote-thread-summaries-v3:` keys in global state). - */ -export async function discoverRemoteEnvironments(): Promise { - const { client } = await openCodexSession(); - try { - for (const method of REMOTE_ENVIRONMENT_LIST_METHODS) { - try { - const result = await client.request(method, {}) as unknown; - const hosts = normalizeHostEntries(result); - if (hosts.length > 0) { - return { hosts, source: `app-server:${method}` }; - } - } catch { - // Method missing or rejected — try the next candidate. - } - } - } finally { - client.close(); - } - return { hosts: [], source: null }; -} - -function normalizeNamedList(result: unknown, idKeys: string[]): string[] { - const raw = listPayload(result); - const out: string[] = []; - for (const entry of raw) { - if (typeof entry === 'string' && entry) out.push(entry); - else if (entry && typeof entry === 'object') { - const row = entry as Record; - for (const key of idKeys) { - if (typeof row[key] === 'string' && row[key]) { - out.push(String(row[key])); - break; - } - } - } - } - return [...new Set(out)].sort(); -} - -function normalizeHostEntries( - result: unknown, -): { hostId: string; hostName: string | null }[] { - const raw = listPayload(result); - const out: { hostId: string; hostName: string | null }[] = []; - for (const entry of raw) { - if (typeof entry === 'string' && entry) { - out.push({ hostId: entry, hostName: null }); - continue; - } - if (!entry || typeof entry !== 'object') continue; - const row = entry as Record; - let hostId: string | null = null; - for (const key of ['hostId', 'id', 'uuid', 'environmentId', 'envId']) { - if (typeof row[key] === 'string' && row[key]) { - hostId = String(row[key]); - break; - } - } - if (!hostId) continue; - let hostName: string | null = null; - for (const key of ['hostName', 'name', 'displayName', 'envName', 'label', 'title']) { - if (typeof row[key] === 'string' && row[key]) { - hostName = String(row[key]); - break; - } - } - out.push({ hostId, hostName }); - } - return out; -} - -function listPayload(result: unknown): unknown[] { - if (Array.isArray(result)) return result; - if (!result || typeof result !== 'object') return []; - const record = result as Record; - for (const key of [ - 'data', - 'providers', - 'modelProviders', - 'hosts', - 'environments', - 'remoteEnvironments', - 'items', - ]) { - if (Array.isArray(record[key])) return record[key] as unknown[]; - } - return []; -} - export async function appServerReadThread({ threadId, limit = 100, @@ -448,80 +300,42 @@ async function listTurnsFull( ): Promise { const collected: unknown[] = []; let cursor: string | undefined; - try { - for (let page = 0; page < 40; page++) { - const result = await client.request('thread/turns/list', { - threadId, - limit: 100, - itemsView: 'full', - ...(cursor ? { cursor } : {}), - }) as { data?: unknown[]; nextCursor?: string | null }; - if (!Array.isArray(result.data)) { - throw new Error(`thread/turns/list missing data array for ${threadId}`); - } - collected.push(...result.data); - if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; - cursor = result.nextCursor; - if (!full && collected.length >= limit) break; - } - } catch (error) { - if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); - // Older daemons may lack itemsView; retry without it, then items/list. - if (collected.length === 0) { - return listTurnsFallback(client, threadId, { limit, full }); - } - throw error; - } - - if (collected.length === 0) { - return listTurnsFallback(client, threadId, { limit, full }); - } - return sliceTurns(normalizeTurns(collected), { limit, full }); -} - -async function listTurnsFallback( - client: AppServerClient, - threadId: string, - { limit, full }: { limit: number; full: boolean }, -): Promise { - for (const method of ['thread/turns/list', 'thread/items/list'] as const) { + let itemsView = true; + let method = 'thread/turns/list'; + const seen = new Set(); + while (collected.length < limit) { + let result: { data?: unknown[]; nextCursor?: string | null }; try { - const collected: unknown[] = []; - let cursor: string | undefined; - for (let page = 0; page < 40; page++) { - const params: Record = { - threadId, - limit: 100, - ...(cursor ? { cursor } : {}), - }; - if (method === 'thread/turns/list') params.itemsView = 'full'; - const result = await client.request(method, params) as { - data?: unknown[]; - nextCursor?: string | null; - }; - if (!Array.isArray(result.data)) break; - collected.push(...result.data); - if (result.nextCursor == null || typeof result.nextCursor !== 'string') break; - cursor = result.nextCursor; - if (!full && collected.length >= limit) break; + result = await client.request(method, { + threadId, + limit: Math.min(100, limit - collected.length), + sortDirection: full ? 'asc' : 'desc', + ...(method === 'thread/turns/list' && itemsView ? { itemsView: 'full' } : {}), + ...(cursor !== undefined ? { cursor } : {}), + }) as typeof result; + } catch (error) { + const code = (error as { rpc?: { code?: number } })?.rpc?.code; + if (collected.length === 0 && code === -32602 && itemsView) { + itemsView = false; + continue; } - if (collected.length > 0) { - return sliceTurns(normalizeTurns(collected), { limit, full }); + if (collected.length === 0 && code === -32601 && method === 'thread/turns/list') { + method = 'thread/items/list'; + continue; } - } catch (error) { - if (isThreadNotLoaded(error)) throw maybeRemoteThreadError(error, threadId); + throw maybeRemoteThreadError(error, threadId); } + if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); + collected.push(...result.data); + if (result.nextCursor == null) break; + if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { + throw new Error(`${method} returned an invalid or repeated cursor`); + } + seen.add(result.nextCursor); + cursor = result.nextCursor; } - throw new Error(`app-server has no turn history for thread ${threadId}`); -} - -function sliceTurns( - turns: ChatGptDesktopTurn[], - { limit, full }: { limit: number; full: boolean }, -): ChatGptDesktopTurn[] { - if (limit <= 0) return turns; - if (full) return turns.slice(0, limit); - return turns.slice(-limit); + const turns = normalizeTurns(collected.slice(0, limit)); + return full ? turns : turns.reverse(); } function normalizeTurns(raw: unknown[]): ChatGptDesktopTurn[] { diff --git a/src/core/chatgpt-desktop/cdp-adapter.ts b/src/core/chatgpt-desktop/cdp-adapter.ts index 749fa09..a20ca32 100644 --- a/src/core/chatgpt-desktop/cdp-adapter.ts +++ b/src/core/chatgpt-desktop/cdp-adapter.ts @@ -8,6 +8,7 @@ import { listThreadsFromDom, openThreadInDom, pickMainWindowTarget, + ReplyTimeoutError, readReplyState, readTurnsFromDom, resolveDurableThreadId, @@ -50,6 +51,7 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { #version: Awaited> | null = null; #pageSessionId: string | null = null; #mainTargetId: string | null = null; + #submittedTurn: { threadId: string; turnKey: string } | null = null; async connect({ port }: { port: number }): Promise { await this.close(); @@ -118,21 +120,28 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } else { await startNewChatInDom(this.#requireSession(), sessionId, { project }); - await delay(300); + await waitForLoadingTaskGone(this.#requireSession(), sessionId, { timeoutMs: openTimeoutMs, threadId: 'new' }); const threads = await listThreadsFromDom(this.#requireSession(), sessionId, { limit: 20 }); const temp = threads.find((t) => t.threadId.startsWith(TEMP_THREAD_ID_PREFIX) && t.selected) ?? threads.find((t) => t.threadId.startsWith(TEMP_THREAD_ID_PREFIX)); if (temp) temporaryThreadId = temp.threadId; } + const before = await readReplyState(this.#requireSession(), sessionId); const { sentVia } = await sendMessageInDom(this.#requireSession(), sessionId, text); let conversationId: string | undefined; if (startedNew || (threadId && isTemporaryDesktopThreadId(threadId))) { const resolveMs = Math.min(openTimeoutMs, DEFAULT_CONVERSATION_RESOLVE_MS); - conversationId = await waitForConversationId(this.#requireSession(), sessionId, { - timeoutMs: resolveMs, - }); + try { + conversationId = await waitForConversationId(this.#requireSession(), sessionId, { + timeoutMs: resolveMs, + }); + } catch (error) { + throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), { + delivery: 'unknown', reason: 'conversation-id-unresolved', + }); + } } const durable = resolveDurableThreadId(conversationId, threadId); @@ -143,6 +152,7 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { ); } + this.#submittedTurn = { threadId: durable, turnKey: before.lastTurnKey }; return { threadId: durable, temporaryThreadId, @@ -163,21 +173,22 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { threadId?: string; timeoutMs?: number; }): Promise { + const deadline = Date.now() + timeoutMs; const sessionId = await this.#ensurePageSession(); + const expectedId = threadId && threadId !== 'new' + ? toAppServerThreadId(threadId) ?? undefined + : this.#submittedTurn ? toAppServerThreadId(this.#submittedTurn.threadId) ?? undefined : undefined; if (threadId && !isTemporaryDesktopThreadId(threadId) && threadId !== 'new') { // Stay on the current chat for temp/new; otherwise ensure the thread is open. - try { - await this.#openAndWait(sessionId, threadId, DEFAULT_OPEN_TIMEOUT_MS); - } catch { - // If already on the thread after send, continue waiting. - } + await this.#openAndWait(sessionId, threadId, Math.min(timeoutMs, DEFAULT_OPEN_TIMEOUT_MS)); } - const baseline = await readReplyState(this.#requireSession(), sessionId); try { const done = await waitForReplyDone(this.#requireSession(), sessionId, { - timeoutMs, - baselineFinalCount: baseline.finalAssistantCount, + timeoutMs: Math.max(0, deadline - Date.now()), + expectedConversationId: expectedId, + baselineTurnKey: this.#submittedTurn && (!threadId || toDesktopThreadId(threadId) === this.#submittedTurn.threadId) + ? this.#submittedTurn.turnKey : undefined, }); const durable = resolveDurableThreadId(done.conversationId, threadId) @@ -197,26 +208,13 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { delivery: 'replied', }; } catch (error) { - const last = await readReplyState(this.#requireSession(), sessionId); - const durable = resolveDurableThreadId(last.conversationId, threadId); - if (last.reply && durable) { - return { - threadId: durable, - conversationId: last.conversationId || toAppServerThreadId(durable) || durable, - reply: last.reply, - backend: 'cdp', - experimental: false, - delivery: 'replied', - }; - } + if (!(error instanceof ReplyTimeoutError)) throw error; return { - threadId: durable ?? (threadId && !isTemporaryDesktopThreadId(threadId) ? threadId : 'unknown'), - conversationId: last.conversationId || undefined, - reply: last.reply, + threadId: threadId ?? 'unknown', + reply: '', backend: 'cdp', experimental: false, - delivery: last.reply ? 'replied' : 'timeout', - ...(error instanceof Error ? {} : {}), + delivery: 'timeout', }; } } @@ -283,6 +281,7 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { await openThreadInDom(this.#requireSession(), sessionId, threadId); await waitForLoadingTaskGone(this.#requireSession(), sessionId, { timeoutMs: openTimeoutMs, + threadId, }); } @@ -320,7 +319,3 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { return this.#session; } } - -function delay(ms: number): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); -} diff --git a/src/core/chatgpt-desktop/cdp-dom.ts b/src/core/chatgpt-desktop/cdp-dom.ts index aa32bfc..9ed14d2 100644 --- a/src/core/chatgpt-desktop/cdp-dom.ts +++ b/src/core/chatgpt-desktop/cdp-dom.ts @@ -237,6 +237,7 @@ export function startNewChatExpression(project?: string): string { preferred.click(); return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; } + return { ok: false, error: 'project-not-found' }; } const buttons = Array.from(document.querySelectorAll('button')); const fallback = buttons.find((btn) => (btn.textContent || '').trim() === 'New chat'); @@ -261,6 +262,8 @@ export const LOADING_TASK_GONE_EXPRESSION = `(() => { export const FOCUS_COMPOSER_EXPRESSION = `(() => { const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); if (!composer) return { ok: false, error: 'composer-not-found' }; + if ((composer.textContent || '').trim()) return { ok: false, error: 'composer-has-draft' }; + if (document.querySelector(${JSON.stringify(STOP_BUTTON_SELECTOR)})) return { ok: false, error: 'reply-in-progress' }; composer.focus(); return { ok: true }; })()`; @@ -289,6 +292,7 @@ export const REPLY_STATE_EXPRESSION = `(() => { conversationId, reply, lastTurnKey, + finalTurnKey: lastFinal?.closest(${JSON.stringify(SELECTORS.turn)})?.getAttribute(${JSON.stringify(ATTR.turnKey)}) || '', }; })()`; @@ -396,12 +400,21 @@ export async function openThreadInDom( export async function waitForLoadingTaskGone( session: CdpSession, sessionId: string, - { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS }: { timeoutMs?: number } = {}, + { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS, threadId }: { timeoutMs?: number; threadId?: string } = {}, ): Promise { const deadline = Date.now() + timeoutMs; while (Date.now() < deadline) { const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { sessionId }); - if (gone) return; + if (gone) { + // A click can resolve before React replaces the previous timeline. + const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; + if (!threadId) return; + if (threadId === 'new' || isTemporaryDesktopThreadId(threadId)) { + const rows = await listThreadsFromDom(session, sessionId, { limit: 200 }); + const selected = rows.find((row) => row.selected); + if (!current && (!selected || isTemporaryDesktopThreadId(selected.threadId))) return; + } else if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; + } await delay(250); } throw new Error( @@ -437,7 +450,7 @@ export async function focusComposer( { sessionId }, ); if (!focused?.ok) { - throw new Error('ChatGPT Desktop composer not found ([data-codex-composer=true])'); + throw new Error(`ChatGPT Desktop composer unavailable: ${focused?.error || 'not found'}`); } } @@ -454,48 +467,34 @@ export async function submitComposerWithEnter( unmodifiedText: '\r', }; await session.send('Input.dispatchKeyEvent', { type: 'rawKeyDown', ...base }, { sessionId }); - await session.send('Input.dispatchKeyEvent', { type: 'char', ...base }, { sessionId }); await session.send('Input.dispatchKeyEvent', { type: 'keyUp', ...base }, { sessionId }); } -/** Fallback submit: click Send when the button exists (composer has text). */ -export async function submitComposerWithButton( - session: CdpSession, - sessionId: string, -): Promise { - const result = await session.evaluate<{ ok: boolean }>( - `(() => { - const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); - if (!btn || btn.disabled) return { ok: false }; - btn.click(); - return { ok: true }; - })()`, - { sessionId }, - ); - return Boolean(result?.ok); -} - export async function sendMessageInDom( session: CdpSession, sessionId: string, text: string, -): Promise<{ sentVia: 'enter' | 'button' }> { +): Promise<{ sentVia: 'enter' }> { await focusComposer(session, sessionId); await session.send('Input.insertText', { text }, { sessionId }); - await submitComposerWithEnter(session, sessionId); - // Enter is the default; fall back to Send if the button is still present (composer still has text). - const sendStillVisible = await session.evaluate( - `(() => { - const btn = document.querySelector(${JSON.stringify(SEND_BUTTON_SELECTOR)}); - return Boolean(btn && !btn.disabled); - })()`, - { sessionId }, - ); - if (sendStillVisible) { - const clicked = await submitComposerWithButton(session, sessionId); - if (clicked) return { sentVia: 'button' }; + try { + await submitComposerWithEnter(session, sessionId); + // Never retry submission just because React has not cleared the button yet. + const deadline = Date.now() + 3000; + while (Date.now() < deadline) { + const cleared = await session.evaluate(`(() => { + const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + return Boolean(composer && !(composer.textContent || '').trim()); + })()`, { sessionId }); + if (cleared) return { sentVia: 'enter' }; + await delay(100); + } + throw new Error('Desktop composer did not acknowledge submission'); + } catch (error) { + throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), { + delivery: 'unknown', reason: 'submission-unconfirmed', + }); } - return { sentVia: 'enter' }; } export type ReplyState = { @@ -504,6 +503,7 @@ export type ReplyState = { conversationId: string; reply: string; lastTurnKey: string; + finalTurnKey?: string; }; export async function readReplyState( @@ -517,6 +517,7 @@ export async function readReplyState( conversationId: String(state?.conversationId ?? ''), reply: String(state?.reply ?? ''), lastTurnKey: String(state?.lastTurnKey ?? ''), + finalTurnKey: String(state?.finalTurnKey ?? ''), }; } @@ -575,13 +576,17 @@ export function resolveDurableThreadId( * Wait until Stop is gone and a new final-assistant marker exists. * Returns reply text + conversation id from the annotation. */ +export class ReplyTimeoutError extends Error {} + export async function waitForReplyDone( session: CdpSession, sessionId: string, { timeoutMs = 120_000, baselineFinalCount = 0, - }: { timeoutMs?: number; baselineFinalCount?: number } = {}, + expectedConversationId, + baselineTurnKey, + }: { timeoutMs?: number; baselineFinalCount?: number; expectedConversationId?: string; baselineTurnKey?: string } = {}, ): Promise<{ reply: string; conversationId: string }> { const deadline = Date.now() + timeoutMs; let sawStop = false; @@ -589,18 +594,22 @@ export async function waitForReplyDone( while (Date.now() < deadline) { const state = await readReplyState(session, sessionId); if (state.stopVisible) sawStop = true; - const hasNewFinal = state.finalAssistantCount > baselineFinalCount && Boolean(state.reply); + expectedConversationId ??= state.conversationId || undefined; + if (expectedConversationId && state.conversationId + && durableThreadKey(state.conversationId) !== durableThreadKey(expectedConversationId)) { + throw new Error('ChatGPT Desktop selected conversation changed while waiting'); + } + const latestIsFinal = Boolean(state.finalTurnKey) && state.finalTurnKey === state.lastTurnKey; + const hasNewFinal = (state.finalAssistantCount > baselineFinalCount || sawStop) + && Boolean(state.reply) && latestIsFinal + && (!baselineTurnKey || state.lastTurnKey !== baselineTurnKey); // Stop appears within ~1s of submit; done when Stop is gone AND a new final exists. if (!state.stopVisible && hasNewFinal && (sawStop || Date.now() - started > 1500)) { return { reply: state.reply, conversationId: state.conversationId }; } await delay(200); } - const last = await readReplyState(session, sessionId); - if (!last.stopVisible && last.finalAssistantCount > baselineFinalCount && last.reply) { - return { reply: last.reply, conversationId: last.conversationId }; - } - throw new Error(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); + throw new ReplyTimeoutError(`ChatGPT Desktop reply did not finish within ${timeoutMs}ms`); } function normalizeTurn(raw: { diff --git a/src/core/chatgpt-desktop/cdp-session.ts b/src/core/chatgpt-desktop/cdp-session.ts index 2485603..3b47bd4 100644 --- a/src/core/chatgpt-desktop/cdp-session.ts +++ b/src/core/chatgpt-desktop/cdp-session.ts @@ -1,6 +1,5 @@ import { CdpUnreachableError } from './errors.js'; import { - assertLoopbackHostname, cdpHttpBase, forceLoopbackWebSocketUrl, } from './loopback.js'; @@ -15,6 +14,7 @@ export type CdpVersionInfo = { type Pending = { resolve: (value: unknown) => void; reject: (error: Error) => void; + timer: ReturnType; }; /** @@ -44,7 +44,10 @@ export class CdpSession { const base = cdpHttpBase(port); let response: Response; try { - response = await fetch(`${base}/json/version`, { signal }); + response = await fetch(`${base}/json/version`, { + signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(5000)]) : AbortSignal.timeout(5000), + redirect: 'error', + }); } catch (error) { throw new CdpUnreachableError( `ChatGPT Desktop CDP not reachable at ${base}/json/version: ` + @@ -56,14 +59,21 @@ export class CdpSession { `ChatGPT Desktop CDP /json/version returned HTTP ${response.status}`, ); } - return (await response.json()) as CdpVersionInfo; + const version = (await response.json()) as CdpVersionInfo; + if (typeof version.webSocketDebuggerUrl === 'string') { + forceLoopbackWebSocketUrl(version.webSocketDebuggerUrl); + } + return version; } static async fetchJsonList(port: number, { signal }: { signal?: AbortSignal } = {}): Promise { const base = cdpHttpBase(port); let response: Response; try { - response = await fetch(`${base}/json/list`, { signal }); + response = await fetch(`${base}/json/list`, { + signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(5000)]) : AbortSignal.timeout(5000), + redirect: 'error', + }); } catch (error) { throw new CdpUnreachableError( `ChatGPT Desktop CDP not reachable at ${base}/json/list: ` + @@ -89,30 +99,38 @@ export class CdpSession { throw new CdpUnreachableError('CDP /json/version omitted webSocketDebuggerUrl'); } const url = forceLoopbackWebSocketUrl(rawUrl); - const parsed = new URL(url); - assertLoopbackHostname(parsed.hostname); + signal?.throwIfAborted(); await new Promise((resolve, reject) => { const ws = new WebSocket(url); this.#ws = ws; + const cleanup = () => { + clearTimeout(timer); + signal?.removeEventListener('abort', onAbort); + }; const onAbort = () => { + cleanup(); ws.close(); - reject(new Error('CDP connect aborted')); + reject(new CdpUnreachableError('CDP connect aborted or timed out')); }; + const timer = setTimeout(onAbort, 5000); signal?.addEventListener('abort', onAbort, { once: true }); ws.addEventListener('open', () => { - signal?.removeEventListener('abort', onAbort); + cleanup(); resolve(); }, { once: true }); ws.addEventListener('error', () => { - signal?.removeEventListener('abort', onAbort); + cleanup(); reject(new CdpUnreachableError(`CDP WebSocket failed for ${url}`)); }, { once: true }); ws.addEventListener('message', (event) => this.#onMessage(event.data)); ws.addEventListener('close', () => { + cleanup(); + reject(new CdpUnreachableError('CDP WebSocket closed before connecting')); this.#closed = true; for (const [, pending] of this.#pending) { - pending.reject(new Error('CDP WebSocket closed')); + clearTimeout(pending.timer); + pending.reject(new CdpUnreachableError('CDP WebSocket closed')); } this.#pending.clear(); }); @@ -134,11 +152,22 @@ export class CdpSession { if (params !== undefined) payload.params = params; if (sessionId !== undefined) payload.sessionId = sessionId; return await new Promise((resolve, reject) => { + const timer = setTimeout(() => { + this.#pending.delete(id); + reject(new CdpUnreachableError(`CDP ${method} timed out`)); + }, 10000); this.#pending.set(id, { + timer, resolve: (value) => resolve(value as T), reject, }); - this.#ws!.send(JSON.stringify(payload)); + try { + this.#ws!.send(JSON.stringify(payload)); + } catch (error) { + clearTimeout(timer); + this.#pending.delete(id); + reject(error); + } }); } @@ -166,6 +195,11 @@ export class CdpSession { close(): void { this.#closed = true; + for (const pending of this.#pending.values()) { + clearTimeout(pending.timer); + pending.reject(new CdpUnreachableError('CDP session closed')); + } + this.#pending.clear(); this.#ws?.close(); this.#ws = null; } @@ -177,10 +211,11 @@ export class CdpSession { } catch { return; } - if (typeof message.id !== 'number') return; + if (!message || typeof message !== 'object' || typeof message.id !== 'number') return; const pending = this.#pending.get(message.id); if (!pending) return; this.#pending.delete(message.id); + clearTimeout(pending.timer); if (message.error) { pending.reject(new Error(message.error.message || 'CDP error')); return; diff --git a/src/core/chatgpt-desktop/errors.ts b/src/core/chatgpt-desktop/errors.ts index d00dc93..b14a9f6 100644 --- a/src/core/chatgpt-desktop/errors.ts +++ b/src/core/chatgpt-desktop/errors.ts @@ -1,4 +1,4 @@ -import { RemoteThreadNotLoadedError as SharedRemoteThreadNotLoadedError } from '../codex/remote-control.js'; +export { RemoteThreadNotLoadedError } from '../codex/remote-control.js'; /** Typed failure when a ChatGPT Desktop CDP/DOM operation is not yet implemented. */ export class NotImplementedError extends Error { @@ -42,26 +42,3 @@ export class CdpUnreachableError extends Error { this.name = 'CdpUnreachableError'; } } - -/** - * Thread exists on a remote-control host and is not loaded on the local - * app-server. Shared with codex send/read paths. - */ -export class RemoteThreadNotLoadedError extends SharedRemoteThreadNotLoadedError { - declare readonly code: 'REMOTE_THREAD_NOT_LOADED'; - declare readonly delivery: 'rejected'; - declare readonly reason: 'remote-thread-not-loaded'; - declare readonly threadId: string; - declare readonly hostId: string | null; - declare readonly hostName: string | null; - declare readonly hint: string; - - constructor( - threadId: string, - hostId: string | null = null, - hostName: string | null = null, - ) { - super(threadId, hostId, hostName); - this.name = 'RemoteThreadNotLoadedError'; - } -} diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index 04f70b1..4d2f559 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -6,7 +6,6 @@ import { appServerSearchThreads, appServerStatusProbe, discoverModelProviders, - discoverRemoteEnvironments, } from './app-server-fallback.js'; import { CdpUnreachableError, NotImplementedError, RemoteThreadNotLoadedError } from './errors.js'; import { resolveCdpPort } from './loopback.js'; @@ -38,7 +37,6 @@ export type ChatGptDesktopFallbacks = { listRemoteThreads?: typeof listRemoteThreadsFromState; listHosts?: typeof listDiscoveredHosts; discoverModelProviders?: typeof discoverModelProviders; - discoverRemoteEnvironments?: typeof discoverRemoteEnvironments; }; const defaultFallbacks: ChatGptDesktopFallbacks = { @@ -49,7 +47,6 @@ const defaultFallbacks: ChatGptDesktopFallbacks = { listRemoteThreads: listRemoteThreadsFromState, listHosts: listDiscoveredHosts, discoverModelProviders, - discoverRemoteEnvironments, }; export type ListThreadsOptions = { @@ -135,10 +132,12 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { } } + const remotes = this.#listRemotes(); let base: ListThreadsResult | null = null; if (appList && cdpList) base = mergeThreadLists(appList, cdpList); else if (appList) base = appList; else if (cdpList) base = cdpList; + else if (remotes.length) base = { backend: 'app-server', limit, threads: [] }; else if (cdpError) throw cdpError; else if (appError) throw appError; else throw new CdpUnreachableError('ChatGPT Desktop listThreads: CDP and app-server unreachable'); @@ -146,9 +145,9 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { return finalizeThreadList(base, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, - remotes: this.#listRemotes(), + remotes, }); } @@ -184,33 +183,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { } } - let hostsSource = 'remote-thread-summaries-v3+local'; - try { - const discoverEnvs = - this.#fallbacks.discoverRemoteEnvironments ?? discoverRemoteEnvironments; - const appHosts = await discoverEnvs(); - if (appHosts.source && appHosts.hosts.length > 0) { - for (const host of appHosts.hosts) { - const existing = byId.get(host.hostId); - if (existing) { - byId.set(host.hostId, { - ...existing, - hostName: existing.hostName ?? host.hostName, - }); - } else { - byId.set(host.hostId, { - hostId: host.hostId, - hostName: host.hostName, - location: 'remote', - threadCount: 0, - }); - } - } - hostsSource = `${appHosts.source}+remote-thread-summaries-v3+local`; - } - } catch { - // App-server remote-env probe unavailable — keep global-state hosts. - } + const hostsSource = 'remote-thread-summaries-v3+local'; // Recount remotes from the parsed summary rows for accuracy. const remoteCounts = new Map(); @@ -244,6 +217,10 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { )].sort(); modelProvidersSource = 'remote-summaries-distinct'; } + modelProviders = [...new Set([ + ...modelProviders, + ...remotes.map((thread) => thread.modelProvider).filter((value): value is string => Boolean(value)), + ])].sort(); return { hosts: withCounts, hostsSource, @@ -274,7 +251,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { const withRemotes = finalizeThreadList(base, { limit: 10_000, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, remotes: this.#listRemotes(), }); const needle = options.query.trim().toLowerCase(); @@ -286,25 +263,26 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { return finalizeThreadList(filtered, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: [], }); } catch (appError) { const cdpList = await this.#tryCdpList({ limit }); - if (!cdpList) throw appError; + const remotes = this.#listRemotes(); + if (!cdpList && !remotes.length) throw appError; const needle = options.query.trim().toLowerCase(); const filtered = { - ...cdpList, + ...(cdpList ?? { backend: 'app-server' as const, limit }), query: options.query, - threads: cdpList.threads.filter((thread) => threadMatchesQuery(thread, needle)), + threads: (cdpList?.threads ?? []).filter((thread) => threadMatchesQuery(thread, needle)), }; return finalizeThreadList(filtered, { limit, host, - modelProvider: options.modelProvider, + modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, - remotes: this.#listRemotes(), + remotes: remotes.filter((thread) => threadMatchesQuery(thread, needle)), }); } } @@ -333,7 +311,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { if (appError instanceof RemoteThreadNotLoadedError) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; - return this.#cdp.readThread({ ...options, limit, full: full || true }); + return this.#cdp.readThread({ ...options, limit, full }); } } @@ -464,12 +442,7 @@ export function mergeThreadLists( for (const thread of cdpList.threads) { if (merged.some((row) => threadIdsEquivalent(row.threadId, thread.threadId))) continue; - merged.push({ - ...thread, - location: thread.location ?? 'local', - hostId: thread.hostId ?? null, - hostName: thread.hostName ?? null, - }); + merged.push(thread); } return { @@ -498,7 +471,14 @@ export function finalizeThreadList( remotes: readonly ChatGptDesktopThread[]; }, ): ListThreadsResult { + const remoteById = new Map(remotes.map((thread) => [ + toAppServerThreadId(thread.threadId) ?? thread.threadId, thread, + ])); const locals = base.threads.map((thread) => { + const remote = remoteById.get(toAppServerThreadId(thread.threadId) ?? thread.threadId); + if (remote && thread.location === undefined) { + return { ...thread, ...remote, selected: thread.selected, pinned: thread.pinned || remote.pinned }; + } const location = thread.location ?? ('local' as const); return { ...thread, @@ -587,11 +567,6 @@ function hostMatches(thread: ChatGptDesktopThread, host: string): boolean { function modelProviderMatches(thread: ChatGptDesktopThread, modelProvider?: string): boolean { if (!modelProvider) return true; - if (!thread.modelProvider) { - // Remote summaries often omit provider — keep them; local rows from a - // filtered thread/list already match the server-side modelProviders filter. - return thread.location === 'remote'; - } return thread.modelProvider === modelProvider; } diff --git a/src/core/chatgpt-desktop/loopback.ts b/src/core/chatgpt-desktop/loopback.ts index e90708e..b2b8f41 100644 --- a/src/core/chatgpt-desktop/loopback.ts +++ b/src/core/chatgpt-desktop/loopback.ts @@ -39,6 +39,7 @@ export function forceLoopbackWebSocketUrl(raw: string): string { throw new CdpHostRejectedError(String(raw)); } assertLoopbackHostname(url.hostname); + if (url.username || url.password || url.hash) throw new CdpHostRejectedError(raw); if (url.protocol !== 'ws:' && url.protocol !== 'wss:') { throw new Error(`Expected ws(s) debugger URL, got ${url.protocol}`); } @@ -56,7 +57,7 @@ export function resolveCdpPort(env: NodeJS.ProcessEnv = process.env, explicit?: } const raw = (env.CHATGPT_DESKTOP_CDP_PORT || '').trim(); if (!raw) return DEFAULT_CDP_PORT; - const port = Number.parseInt(raw, 10); + const port = /^\d+$/.test(raw) ? Number(raw) : NaN; if (!Number.isInteger(port) || port < 1 || port > 65535) { throw new RangeError('CHATGPT_DESKTOP_CDP_PORT must be an integer 1-65535'); } diff --git a/src/core/chatgpt-desktop/remote-threads.ts b/src/core/chatgpt-desktop/remote-threads.ts index 6bdfb45..2e7676e 100644 --- a/src/core/chatgpt-desktop/remote-threads.ts +++ b/src/core/chatgpt-desktop/remote-threads.ts @@ -9,9 +9,8 @@ * SSH remoting is intentionally not implemented here (follow-up). */ -import { readFileSync } from 'node:fs'; -import { homedir } from 'node:os'; -import { join } from 'node:path'; +import { loadCodexGlobalState } from '../codex/remote-control.js'; +export { codexGlobalStatePath, loadCodexGlobalState } from '../codex/remote-control.js'; import { toAppServerThreadId, toDesktopThreadId } from './thread-ids.js'; import type { ChatGptDesktopThread } from './types.js'; @@ -35,30 +34,6 @@ export type RemoteThreadLookup = { readonly thread: RemoteThreadRecord | null; }; -export function codexGlobalStatePath(env: NodeJS.ProcessEnv = process.env): string { - const home = env.CODEX_HOME || join(homedir(), '.codex'); - return join(home, '.codex-global-state.json'); -} - -/** Read and JSON-parse the Desktop global state file; null when missing/invalid. */ -export function loadCodexGlobalState( - env: NodeJS.ProcessEnv = process.env, -): Record | null { - let raw: string; - try { - raw = readFileSync(codexGlobalStatePath(env), 'utf8'); - } catch { - return null; - } - try { - const data = JSON.parse(raw) as unknown; - if (!data || typeof data !== 'object' || Array.isArray(data)) return null; - return data as Record; - } catch { - return null; - } -} - /** * Parse every `remote-thread-summaries-v3:` entry into flat remote * thread rows. Unknown/malformed entries are skipped. diff --git a/src/core/chatgpt-desktop/routes.ts b/src/core/chatgpt-desktop/routes.ts index 258651f..801082e 100644 --- a/src/core/chatgpt-desktop/routes.ts +++ b/src/core/chatgpt-desktop/routes.ts @@ -66,7 +66,7 @@ export const sendSchema = z .object({ port: z.number().int().min(1).max(65535).optional(), threadId: threadId.optional(), - text: z.string().min(1).max(100_000), + text: z.string().trim().min(1).max(100_000), project: z.string().min(1).max(256).optional(), openTimeoutMs: z.number().int().min(1).max(600_000).default(90_000), }) @@ -88,25 +88,35 @@ export const resultSchema = z export type OperationResult = z.infer; +// The Desktop has one selected conversation and composer. Keep route calls +// from closing each other's sessions or typing into each other's chats. +let operationQueue: Promise = Promise.resolve(); + async function withAdapter( port: number | undefined, run: (adapter: ReturnType) => Promise, ): Promise { - const adapter = getChatGptDesktopAdapter(); - const resolved = resolveCdpPort(process.env, port); - try { - await adapter.connect({ port: resolved }); - } catch { - // status/list/search/read may still succeed via HTTP probe or app-server. - } - return run(adapter); + const operation = operationQueue.then(async () => { + const adapter = getChatGptDesktopAdapter(); + const resolved = resolveCdpPort(process.env, port); + try { + try { + await adapter.connect({ port: resolved }); + } catch { + // Reads may still succeed through the app-server. + } + return await run(adapter); + } finally { + await adapter.close(); + } + }); + operationQueue = operation.catch(() => {}); + return operation; } function asResult(value: object): OperationResult { - const cleaned = Object.fromEntries( - Object.entries(value).filter(([, entry]) => entry !== undefined), - ); - return resultSchema.parse(cleaned); + // Match the wire representation, including optional fields nested in turns. + return resultSchema.parse(JSON.parse(JSON.stringify(value))); } function mapError(error: unknown): OperationResult { @@ -224,6 +234,7 @@ export async function readThreadOperation( export async function sendOperation(input: z.infer): Promise { try { + input = sendSchema.parse(input); const out = await withAdapter(input.port, (adapter) => adapter.sendMessage({ threadId: input.threadId, @@ -263,7 +274,7 @@ export function resultText(result: OperationResult): string { const backend = result.appServerFallback && typeof result.appServerFallback === 'object' ? ` cdp + app-server probe` : ''; - return `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; + return result.message ? String(result.message) : `ChatGPT Desktop CDP reachable on 127.0.0.1:${result.port}${backend}`; } if (result.reachable === false) return String(result.message ?? 'ChatGPT Desktop CDP unreachable'); if (Array.isArray(result.hosts)) { diff --git a/src/core/codex-bridge.js b/src/core/codex-bridge.js index 0ac69cb..a6c8e28 100644 --- a/src/core/codex-bridge.js +++ b/src/core/codex-bridge.js @@ -1120,6 +1120,7 @@ export async function readCodexThread(threadId, { limit = 100, env = process.env } const turns = []; let cursor; + const seen = new Set(); for (let page = 0; page < 40 && turns.length < limit; page++) { let out; try { @@ -1127,6 +1128,7 @@ export async function readCodexThread(threadId, { limit = 100, env = process.env threadId: bare, limit: Math.min(100, limit - turns.length), itemsView: "full", + sortDirection: "desc", ...(cursor !== undefined ? { cursor } : {}), }); } catch (err) { @@ -1138,8 +1140,12 @@ export async function readCodexThread(threadId, { limit = 100, env = process.env throw new CodexProtocolError("thread/turns/list", "missing `data` array"); } for (const row of out.data) turns.push(row); - if (out.nextCursor == null || typeof out.nextCursor !== "string") break; - cursor = out.nextCursor; + cursor = out.nextCursor ?? null; + if (cursor === null) break; + if (typeof cursor !== "string" || !cursor || seen.has(cursor)) { + throw new CodexProtocolError("thread/turns/list", "invalid or repeated cursor"); + } + seen.add(cursor); } return { threadId: bare, diff --git a/src/core/codex/routes.ts b/src/core/codex/routes.ts index e110d74..d563611 100644 --- a/src/core/codex/routes.ts +++ b/src/core/codex/routes.ts @@ -24,13 +24,13 @@ export const observationFields = { }; export const sendFields = { ...observationFields, - correlationId: id.optional(), envelope: z.boolean().optional(), hop: z.number().int().min(0).optional(), - replyTo: id.optional(), expectedTurnId: id.optional(), + correlationId: bareId.optional(), envelope: z.boolean().optional(), hop: z.number().int().min(0).optional(), + replyTo: bareId.optional(), expectedTurnId: bareId.optional(), whenBusy: z.enum(['reject', 'queue', 'steer']).default('reject'), wait: z.boolean().default(false), maxOutputBytes: z.number().int().min(1).max(4194304).optional(), }; export const sendSchema = z.object({ ...sendFields, message: z.string().min(1).max(4194304) }).strict(); -export const waitSchema = z.object({ ...observationFields, turnId: id, messageId: id.optional(), maxOutputBytes: z.number().int().min(1).max(4194304).optional() }).strict(); +export const waitSchema = z.object({ ...observationFields, turnId: bareId, messageId: bareId.optional(), maxOutputBytes: z.number().int().min(1).max(4194304).optional() }).strict(); export const watchSchema = z.object({ ...observationFields, maxEvents: z.number().int().min(1).max(500).default(100) }).strict(); export const threadsSchema = z.object({ limit: z.number().int().min(1).max(200).default(20), cursor: z.string().min(1).max(4096).optional() }).strict(); export const resultSchema = z.object({ diff --git a/src/core/codex/thread-id.js b/src/core/codex/thread-id.js index 565c0c9..9dfe6be 100644 --- a/src/core/codex/thread-id.js +++ b/src/core/codex/thread-id.js @@ -12,7 +12,8 @@ export const TEMP_THREAD_ID_PREFIX = 'local:client-new-thread:'; const ID_PATTERN = /^[A-Za-z0-9_.:-]{1,128}$/; export function isTemporaryDesktopThreadId(threadId) { - return typeof threadId === 'string' && threadId.startsWith(TEMP_THREAD_ID_PREFIX); + return typeof threadId === 'string' + && (threadId.startsWith(TEMP_THREAD_ID_PREFIX) || threadId.startsWith('client-new-thread:')); } /** @@ -38,10 +39,3 @@ export function normalizeCodexThreadId(threadId) { } return bare; } - -/** True when the value looks like a Desktop-prefixed durable id. */ -export function hasLocalThreadPrefix(threadId) { - return typeof threadId === 'string' - && threadId.startsWith(LOCAL_THREAD_ID_PREFIX) - && !isTemporaryDesktopThreadId(threadId); -} diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx index d15dd9e..c02180a 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list hosts', description: - 'Discover ChatGPT Desktop hosts and modelProviders at runtime — never hardcode them. Hosts: always local, plus every remote-thread-summaries-v3: key from ~/.codex/.codex-global-state.json (friendly names + thread counts), merged with any app-server remote-environment/connection list method when present. Providers: app-server list method when present, else distinct modelProvider values from thread/list. New machines/connections Zack adds later show up with no code change. Result includes hostsSource and modelProvidersSource.', + 'Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource', annotations: { readOnlyHint: true }, inputSchema, resultSchema, diff --git a/test/codex-bridge.test.js b/test/codex-bridge.test.js index 6815d06..4fa1209 100644 --- a/test/codex-bridge.test.js +++ b/test/codex-bridge.test.js @@ -1643,6 +1643,7 @@ test("readCodexThread uses thread/read without includeTurns and pages thread/tur try { const out = await readCodexThread("local:t-1", { env: { CODEX_HOME: fake.home }, limit: 10 }); assert.equal(out.threadId, "t-1"); + assert.equal(out.nextCursor, null); assert.equal(out.thread.name, "History"); assert.deepEqual(out.turns.map((t) => t.id), ["turn-a", "turn-b"]); assert.deepEqual(seen[0], { method: "thread/read", params: { threadId: "t-1" } }); @@ -1651,11 +1652,13 @@ test("readCodexThread uses thread/read without includeTurns and pages thread/tur threadId: "t-1", limit: 10, itemsView: "full", + sortDirection: "desc", }); assert.deepEqual(seen[2].params, { threadId: "t-1", limit: 9, itemsView: "full", + sortDirection: "desc", cursor: "page-2", }); } finally { @@ -1669,4 +1672,5 @@ test("normalizeCodexThreadId strips local: and rejects temporary Desktop rows", assert.equal(normalizeCodexThreadId("abc-123"), "abc-123"); assert.equal(isTemporaryDesktopThreadId("local:client-new-thread:x"), true); assert.throws(() => normalizeCodexThreadId("local:client-new-thread:x"), /Temporary Desktop/); + assert.throws(() => normalizeCodexThreadId("client-new-thread:x"), /Temporary Desktop/); }); diff --git a/tests/route-unit/chatgpt-desktop-review.test.ts b/tests/route-unit/chatgpt-desktop-review.test.ts new file mode 100644 index 0000000..ca661c9 --- /dev/null +++ b/tests/route-unit/chatgpt-desktop-review.test.ts @@ -0,0 +1,246 @@ +import { createServer } from 'node:http'; +import type { AddressInfo } from 'node:net'; +import { afterEach, expect, it, rstest } from '@rstest/core'; +import { CdpSession } from '../../src/core/chatgpt-desktop/cdp-session.js'; +import { CdpChatGptDesktopAdapter } from '../../src/core/chatgpt-desktop/cdp-adapter.js'; +import { ChatGptDesktopFacade, finalizeThreadList, setChatGptDesktopAdapterForTests } from '../../src/core/chatgpt-desktop/facade.js'; +import { CONVERSATION_ID_EXPRESSION, REPLY_STATE_EXPRESSION, LOADING_TASK_GONE_EXPRESSION, waitForReplyDone } from '../../src/core/chatgpt-desktop/cdp-dom.js'; +import { sendSchema, waitSchema } from '../../src/core/codex/routes.js'; +import { statusOperation } from '../../src/core/chatgpt-desktop/routes.js'; +import type { ChatGptDesktopAdapter } from '../../src/core/chatgpt-desktop/adapter.js'; + +const row = (threadId: string) => ({ threadId, title: threadId, pinned: false, selected: false, kind: 'codex' }); +afterEach(() => { rstest.restoreAllMocks(); setChatGptDesktopAdapterForTests(null); }); + +it('rejects CDP HTTP redirects without contacting their destination', async () => { + let redirected = 0; + const server = createServer((req, res) => { + if (req.url === '/escaped') { redirected++; res.end('{}'); } + else { res.writeHead(302, { location: '/escaped' }); res.end(); } + }); + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)); + try { + const { port } = server.address() as AddressInfo; + await expect(CdpSession.fetchVersion(port)).rejects.toThrow(); + await expect(CdpSession.fetchJsonList(port)).rejects.toThrow(); + expect(redirected).toBe(0); + } finally { server.closeAllConnections(); await new Promise(resolve => server.close(() => resolve())); } +}); + +it('normalizes only thread IDs, preserving correlation, message and turn IDs', () => { + const sent = sendSchema.parse({ threadId: 'local:thread', message: 'hi', correlationId: 'local:corr', replyTo: 'local:msg', expectedTurnId: 'local:turn' }); + expect(sent).toMatchObject({ threadId: 'thread', correlationId: 'local:corr', replyTo: 'local:msg', expectedTurnId: 'local:turn' }); + expect(waitSchema.parse({ threadId: 'local:thread', turnId: 'local:turn', messageId: 'local:msg' })).toMatchObject({ threadId: 'thread', turnId: 'local:turn', messageId: 'local:msg' }); +}); + +it('keeps remote ownership for a CDP sidebar row and excludes unknown providers', () => { + const remote = { ...row('local:remote'), location: 'remote' as const, hostId: 'fixture-new-host', hostName: 'Fixture Host', modelProvider: 'fixture-new-provider' }; + const base = { backend: 'cdp' as const, limit: 50, threads: [row('local:remote')] }; + const listed = finalizeThreadList(base, { limit: 50, remotes: [remote], host: remote.hostId, modelProvider: remote.modelProvider }); + expect(listed.threads).toHaveLength(1); + expect(listed.threads[0]).toMatchObject({ location: 'remote', hostId: remote.hostId }); + expect(finalizeThreadList({ ...base, threads: [] }, { limit: 50, remotes: [{ ...remote, modelProvider: null }], modelProvider: remote.modelProvider }).threads).toEqual([]); +}); + +it('filters remote search results even when app-server fails', async () => { + const facade = new ChatGptDesktopFacade({ connect: async () => {}, listThreads: async () => ({ backend: 'cdp', limit: 50, threads: [] }) } as unknown as ChatGptDesktopAdapter, 9222, { + searchThreads: async () => { throw new Error('offline'); }, + listRemoteThreads: () => [{ ...row('local:unrelated'), location: 'remote', hostId: 'fixture', hostName: null }], + } as never); + expect((await facade.searchThreads({ query: 'needle' })).threads).toEqual([]); +}); + +async function connectedAdapter(state: Record, open = true) { + rstest.spyOn(CdpSession.prototype, 'connect').mockResolvedValue({}); + rstest.spyOn(CdpSession.prototype, 'closed', 'get').mockReturnValue(false); + rstest.spyOn(CdpSession.prototype, 'send').mockImplementation(async (method) => (method === 'Target.getTargets' + ? { targetInfos: [{ targetId: 'main', type: 'page', url: 'app://-/index.html' }] } + : { sessionId: 'page' }) as never); + rstest.spyOn(CdpSession.prototype, 'evaluate').mockImplementation(async expression => { + if (expression === REPLY_STATE_EXPRESSION) return state as never; + if (expression === CONVERSATION_ID_EXPRESSION) return 'thread' as never; + if (expression === LOADING_TASK_GONE_EXPRESSION) return true as never; + return { ok: open, error: 'thread-not-found' } as never; + }); + const adapter = new CdpChatGptDesktopAdapter(); + await adapter.connect({ port: 9222 }); + return adapter; +} + +it('does not report a streaming partial reply as completed after timeout', async () => { + const adapter = await connectedAdapter({ stopVisible: true, finalAssistantCount: 1, reply: 'partial', conversationId: 'thread', lastTurnKey: 'turn', finalTurnKey: 'turn' }); + expect((await adapter.waitForReply({ threadId: 'local:thread', timeoutMs: 1 })).delivery).toBe('timeout'); +}); + +it('propagates failure to open the requested thread instead of reading another chat', async () => { + const adapter = await connectedAdapter({ stopVisible: false, finalAssistantCount: 1, reply: 'wrong chat', conversationId: 'other', lastTurnKey: 'turn', finalTurnKey: 'turn' }, false); + await expect(adapter.waitForReply({ threadId: 'local:thread', timeoutMs: 1 })).rejects.toThrow('not found'); +}); + +it('recognizes completion when a final marker already existed while streaming', async () => { + let call = 0; + const session = { evaluate: async () => ({ stopVisible: call++ === 0, finalAssistantCount: 1, reply: 'final', conversationId: 'thread', lastTurnKey: 'turn', finalTurnKey: 'turn' }) }; + await expect(waitForReplyDone(session as never, 'page', { timeoutMs: 300, baselineFinalCount: 1 })).resolves.toMatchObject({ reply: 'final' }); +}); + +it('serializes Desktop operations and closes each connection on completion', async () => { + let active = 0; + let maxActive = 0; + let closed = 0; + setChatGptDesktopAdapterForTests({ + connect: async () => { active++; maxActive = Math.max(maxActive, active); }, + status: async () => { await new Promise(resolve => setTimeout(resolve, 10)); return { reachable: true, port: 9222, host: '127.0.0.1', message: 'ok', exitCode: 0 }; }, + close: async () => { active--; closed++; }, + } as unknown as ChatGptDesktopAdapter); + await Promise.all([statusOperation({}), statusOperation({})]); + expect(maxActive).toBe(1); + expect(closed).toBe(2); +}); + +it('waits through an old conversation rendered before Loading task appears', async () => { + const { waitForLoadingTaskGone } = await import('../../src/core/chatgpt-desktop/cdp-dom.js'); + let reads = 0; + const session = { evaluate: async (expression: string) => expression === CONVERSATION_ID_EXPRESSION ? (++reads === 1 ? 'old-thread' : 'wanted-thread') : true }; + await waitForLoadingTaskGone(session as never, 'page', { timeoutMs: 600, threadId: 'local:wanted-thread' }); + expect(reads).toBe(2); +}); + +it('does not accept an old final reply when the latest user turn is unanswered', async () => { + const session = { evaluate: async () => ({ stopVisible: false, finalAssistantCount: 1, reply: 'old', conversationId: 'thread', lastTurnKey: 'new-turn', finalTurnKey: 'old-turn' }) }; + await expect(waitForReplyDone(session as never, 'page', { timeoutMs: 10 })).rejects.toThrow('did not finish'); +}); + +it('rejects a conversation switch while waiting for a specific thread', async () => { + const session = { evaluate: async () => ({ stopVisible: false, finalAssistantCount: 1, reply: 'other', conversationId: 'other', lastTurnKey: 'turn', finalTurnKey: 'turn' }) }; + await expect(waitForReplyDone(session as never, 'page', { timeoutMs: 10, expectedConversationId: 'wanted' })).rejects.toThrow('changed'); +}); + +it('does not silently create a generic chat when the requested project is missing', async () => { + const { startNewChatExpression } = await import('../../src/core/chatgpt-desktop/cdp-dom.js'); + let clicks = 0; + const document = { querySelector: () => null, querySelectorAll: () => [{ textContent: 'New chat', click: () => clicks++ }] }; + const result = new Function('document', `return ${startNewChatExpression('fixture-project')}`)(document); + expect(result.ok).toBe(false); + expect(clicks).toBe(0); +}); + +it('rejects non-loopback debugger URLs even for HTTP-only status discovery', async () => { + const server = createServer((_req, res) => res.end(JSON.stringify({ webSocketDebuggerUrl: 'ws://192.0.2.1:9222/devtools/browser/x' }))); + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)); + try { + await expect(CdpSession.fetchVersion((server.address() as AddressInfo).port)).rejects.toMatchObject({ code: 'CDP_HOST_REJECTED' }); + } finally { server.closeAllConnections(); await new Promise(resolve => server.close(() => resolve())); } +}); + +it('aborts a CDP HTTP response that never finishes its body', async () => { + const server = createServer((_req, res) => { res.writeHead(200); res.write('{'); }); + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)); + try { + await expect(CdpSession.fetchVersion((server.address() as AddressInfo).port, { signal: AbortSignal.timeout(30) })).rejects.toThrow(); + } finally { server.closeAllConnections(); await new Promise(resolve => server.close(() => resolve())); } +}); + +it('reads empty history and requests explicit ascending/full or descending/recent pages', async () => { + const bridge = await import('../../src/core/codex-bridge.js'); + const { appServerReadThread } = await import('../../src/core/chatgpt-desktop/app-server-fallback.js'); + const calls: Array> = []; + let empty = true; + rstest.spyOn(bridge, 'openCodexSession').mockResolvedValue({ client: { + close() {}, + async request(method: string, params: Record) { + if (method === 'thread/read') return { thread: { id: 'review-thread' } }; + calls.push(params); + const ids = params.sortDirection === 'asc' ? ['old', 'new'] : ['new', 'old']; + return { data: empty ? [] : ids.map(id => ({ id, items: [] })), nextCursor: null }; + }, + } } as never); + expect((await appServerReadThread({ threadId: 'review-thread' })).turns).toEqual([]); + empty = false; + expect((await appServerReadThread({ threadId: 'review-thread', limit: 2 })).turns.map(t => t.turnKey)).toEqual(['history-content:turn:old', 'history-content:turn:new']); + await appServerReadThread({ threadId: 'review-thread', limit: 2, full: true }); + expect(calls.map(c => c.sortDirection)).toEqual(['desc', 'desc', 'asc']); + expect(calls.at(-1)?.limit).toBe(2); +}); + +it('keeps provider discovery dynamic and combines local and remote provider IDs', async () => { + const provider = `provider-${crypto.randomUUID()}`; + const host = `host-${crypto.randomUUID()}`; + const remote = { ...row('local:remote'), location: 'remote' as const, hostId: host, hostName: host, modelProvider: provider }; + const facade = new ChatGptDesktopFacade({} as ChatGptDesktopAdapter, 9222, { + listThreads: async () => ({ threads: [], backend: 'app-server', limit: 50 }), + listRemoteThreads: () => [remote], + listHosts: () => [], + discoverModelProviders: async () => ({ providers: ['fixture-local-provider'], source: 'thread/list-distinct' }), + } as never); + const result = await facade.listHosts(); + expect(result.hosts.map(h => h.hostId)).toContain(host); + expect(result.modelProviders).toContain(provider); +}); + +it('bounds an unanswered CDP command and rejects pending commands on close', async () => { + let socket: EventTarget; + class SilentSocket extends EventTarget { + static OPEN = 1; + static CLOSED = 3; + readyState = 1; + constructor() { super(); socket = this; } + send() {} + close() { this.readyState = 3; this.dispatchEvent(new Event('close')); } + } + rstest.stubGlobal('WebSocket', SilentSocket); + rstest.useFakeTimers(); + rstest.spyOn(CdpSession, 'fetchVersion').mockResolvedValue({ webSocketDebuggerUrl: 'ws://127.0.0.1:9222/test' }); + const session = new CdpSession(9222); + try { + const connecting = session.connect(); + await Promise.resolve(); + socket!.dispatchEvent(new Event('open')); + await connecting; + const timedOut = expect(session.send('Runtime.evaluate')).rejects.toThrow('timed out'); + await rstest.advanceTimersByTimeAsync(10001); + await timedOut; + const closed = expect(session.send('Target.getTargets')).rejects.toThrow('closed'); + session.close(); + await closed; + } finally { session.close(); rstest.useRealTimers(); rstest.unstubAllGlobals(); } +}); + +it('submits once even while the Send button lingers, and refuses an existing draft', async () => { + const { FOCUS_COMPOSER_EXPRESSION, sendMessageInDom } = await import('../../src/core/chatgpt-desktop/cdp-dom.js'); + const commands: string[] = []; + const session = { + evaluate: async (expression: string) => expression === FOCUS_COMPOSER_EXPRESSION ? { ok: true } : true, + send: async (method: string, params: Record) => { commands.push(`${method}:${params.type || ''}`); }, + }; + expect(await sendMessageInDom(session as never, 'page', 'hello')).toEqual({ sentVia: 'enter' }); + expect(commands).toEqual(['Input.insertText:', 'Input.dispatchKeyEvent:rawKeyDown', 'Input.dispatchKeyEvent:keyUp']); + const document = { querySelector: () => ({ textContent: 'unsent draft', focus: () => { throw new Error('must not focus'); } }) }; + expect(new Function('document', `return ${FOCUS_COMPOSER_EXPRESSION}`)(document)).toEqual({ ok: false, error: 'composer-has-draft' }); +}); + +it('does not relabel a failed Enter acknowledgment as a safe rejection', async () => { + const { sendMessageInDom } = await import('../../src/core/chatgpt-desktop/cdp-dom.js'); + const session = { + evaluate: async () => ({ ok: true }), + send: async (method: string) => { if (method === 'Input.dispatchKeyEvent') throw new Error('lost connection'); }, + }; + await expect(sendMessageInDom(session as never, 'page', 'hello')).rejects.toMatchObject({ delivery: 'unknown', reason: 'submission-unconfirmed' }); +}); + +it('waits for the real conversation when given the special new-thread target', async () => { + const state = { stopVisible: true, finalAssistantCount: 1, reply: 'final', conversationId: 'thread', lastTurnKey: 'turn', finalTurnKey: 'turn' }; + const adapter = await connectedAdapter(state); + const timer = setTimeout(() => { state.stopVisible = false; }, 10); + try { + expect(await adapter.waitForReply({ threadId: 'new', timeoutMs: 500 })).toMatchObject({ threadId: 'local:thread', delivery: 'replied' }); + } finally { clearTimeout(timer); } +}); + +it('serializes nested optional fields without rejecting successful reads', async () => { + const { readThreadOperation } = await import('../../src/core/chatgpt-desktop/routes.js'); + setChatGptDesktopAdapterForTests({ + connect: async () => {}, close: async () => {}, + readThread: async () => ({ threadId: 'thread', backend: 'cdp', turns: [{ turnKey: 'turn', role: 'assistant', text: 'reply', userText: undefined }], limit: 1, full: false }), + } as unknown as ChatGptDesktopAdapter); + expect(await readThreadOperation({ threadId: 'thread', limit: 1, full: false, openTimeoutMs: 100 })).toMatchObject({ exitCode: 0, turns: [{ text: 'reply' }] }); +}); diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index cbc5ac1..77f7237 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -1025,13 +1025,12 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () providers: ['openai', 'anthropic'], source: 'thread/list-distinct' as const, }), - discoverRemoteEnvironments: async () => ({ hosts: [], source: null }), }, ); const hostList = await facade.listHosts(); expect(hostList.hostsSource).toBe('remote-thread-summaries-v3+local'); expect(hostList.modelProvidersSource).toBe('thread/list-distinct'); - expect(hostList.modelProviders).toEqual(['openai', 'anthropic']); + expect(hostList.modelProviders).toEqual(['anthropic', 'openai']); expect(hostList.hosts.find((h) => h.hostId === 'local')?.threadCount).toBe(1); expect(hostList.hosts.find((h) => h.hostId === 'host-macbook')?.threadCount).toBe(2); @@ -1166,7 +1165,6 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () providers: ['brand-new-provider'], source: 'thread/list-distinct' as const, }), - discoverRemoteEnvironments: async () => ({ hosts: [], source: null }), listHosts: (processEnv, opts) => listDiscoveredHosts(env, opts), }, ); From 76ce81613307f3a2afc8345f0ed09246f7bee6fb Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 29 Sep 2026 02:26:53 +0000 Subject: [PATCH 20/26] chore: refresh artifact snapshot after CDP review fixes Rebuild agent-bundle evidence/manifest so sourceInputs match the Desktop CDP isolation/reply-tracking commit that just landed. Co-authored-by: Zack Jackson --- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 0f816d5..3437adb 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"ef7223d4be069f7e989a2c9e541f7cff510d46b3c126ceff5c907d666f87276b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"f563c98eb0a699dc9bcc787c2d6dfa59b32026cd3fd113ea399c047788c9316d"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"7de9950e8f436024ef8bef47c406f7c4f720bd395de466a2593cb8fc6bdaa74b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b401a79c4f972b075d61602627f53472cdea0ebbb44e0995c49bbf0bbdcbacfe"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"2d6a8f6474f457729ad16d53810bea3098ecd94ee261e33b4eff60c3c879e74f"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"ef7223d4be069f7e989a2c9e541f7cff510d46b3c126ceff5c907d666f87276b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"f563c98eb0a699dc9bcc787c2d6dfa59b32026cd3fd113ea399c047788c9316d"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"7de9950e8f436024ef8bef47c406f7c4f720bd395de466a2593cb8fc6bdaa74b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b401a79c4f972b075d61602627f53472cdea0ebbb44e0995c49bbf0bbdcbacfe"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"2d6a8f6474f457729ad16d53810bea3098ecd94ee261e33b4eff60c3c879e74f"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 0f0c328..b0c9ccb 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"2801fc8bb76c233d7ef0a7ba2d105ee662549c7d3def3caf521129751449e790","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"bb9cf27257103b6a3ecf613b483a24a2a4ec192208a103f731368bbc31e6a5bc","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"87d63f5b0bada3621036657c544f9d5345619add70040b4ec201760541ffae7a"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"plugin/artifact/.agents/plugins/marketplace.json","sha256":"fb3366f72f193629c7d4209091e97108a3c263474f060f344e2cba22bf0fe23b"},{"executable":false,"path":"plugin/artifact/.claude-plugin/marketplace.json","sha256":"581b674cc9c0d0770c57d90c8bf9e8cbe5fd61431dc668cf37ef2e2f41f1f101"},{"executable":false,"path":"plugin/artifact/.claude-plugin/plugin.json","sha256":"82898ac16c42a9765c7b4db5614ed4700774060612d76a8bc7bf521772f32f46"},{"executable":false,"path":"plugin/artifact/.codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"executable":false,"path":"plugin/artifact/.codex-plugin/plugin.json","sha256":"91f82ce1f58fe0ac6fdd4997a13ede64e74a07a830acaf90e84148e4e3facb62"},{"executable":false,"path":"plugin/artifact/.cursor-plugin/marketplace.json","sha256":"5a3e70383773b9588887a10327b3912a99dad6ce4776ecbb87ebe9e18ad27e34"},{"executable":false,"path":"plugin/artifact/.cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"executable":false,"path":"plugin/artifact/.cursor-plugin/plugin.json","sha256":"3cc7d4307cbfde391f087069a00dea2585052ade8476c926ff16a91f44eff447"},{"executable":false,"path":"plugin/artifact/.mcp.json","sha256":"2539f66ffcb1c98a365f078c63122a1c25b7c7625f91314467843bde7628907b"},{"executable":false,"path":"plugin/artifact/agent-bundle.compile-evidence.json","sha256":"06b645955133c9ef447527df64ab81a7fbd044714bf5b757e3842fe1ad836c99"},{"executable":false,"path":"plugin/artifact/agent-bundle.manifest.json","sha256":"11ea7fd533a82996beae587b0578bed15e6ed14007166d85ddb0f6948a17f250"},{"executable":false,"path":"plugin/artifact/INSTALL.md","sha256":"05d6646fbe837407227fe482ca454224ff9fad86561b6366b0215b1148e7bc36"},{"executable":false,"path":"plugin/artifact/install.mjs","sha256":"2beddd1bd9ef0b575e5dd6d8f0dd83c734ce296b4b941bb0bb3098fc75ef15d1"},{"executable":false,"path":"plugin/artifact/mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"executable":false,"path":"plugin/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"25c576a53c0b554136b1712f801d20837b7f14173acaf2bfe816da556ac64f18"},{"executable":false,"path":"plugin/artifact/mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"3832b6ed0cd8e2a96df26864407f99cb82f5a791ddb1984136897eb20d8afccb"},{"executable":false,"path":"plugin/artifact/plugin.json","sha256":"a6b67f279bc827ea40117d3d0a48e64a1a14774173ade8a3775e1aa30812ed2e"},{"executable":false,"path":"plugin/artifact/skills/talk-to-grok-bot/SKILL.md","sha256":"ed7cca3e35080a8eb86b57e5b913172e26bccf25f45443255fcb2aa524abf91b"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"5cdd948062f0ba15af16917870c74d77259ed97af008d15bce95095e246129c9"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"659483af940524ef155f505a0f4235ef76ed50a849a86fa1d7834256a0588838"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5ba4f07e35239c59cff2815eadb957fb13cf682d12bb25bf192f6bd8691eb4a5"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"14cd66c5b689ff9f587f7ca4eff32320903c7fb911f4306724141ceef7d9041a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"429ccecd068b34f7fb230a14f0b6ca662d2e5d61b6edc8d3fdfd54d91617d4ed"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"e72142dd6a4dfe49f103ca660f0dfe8a0a0df8759a8707d0a62cbad2b6df5c2c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"a33860336ea2c336d2f0a17168502f8dad37bce7de671ebc826a1652fd69c196"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"00a6c3f836e13e86bc8ffdcc621e3e360fe451e57d3c4af31f40a50bbd5ac65d"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"1bd8d2a4dba6d848331d5656c7e00649992435bcbd1f87903adc0a26179ebadf"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"143f138d886b4f20fa65bd61d01d01df19103cc386fffd3e331176e721a307e9"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"d260ca3a9d150900cc1a2e4f3df2e8f3712714ed9be2ecd6a646eda6e7b1b8d4"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"f2e1131e6f973fe8efb277022e77731196fbdaa226bede64ecfeae9eb0d0de2c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"f4d5e0377cdb7297754d3220c1935fc65bfb5f605b3bc0f15f5ff328f0ce3b63"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"5d7b69f5b0502039a086f1903951d735b02fb57107214b0f4d4d6abc349f352f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"521496fdfaff13cb55f4decb9e78ebaa1d2e35e7bfcc38cc887375b200724961"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"3de602b6e5ac42cfe0f2fe65a9c060a3d54bf8891eb8579538d412d7cfdb6c07"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"047c6bd900de50ae5ef8b1ac9391fdcaee5068af59f16cf1c2c3e23d0aea5385"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"dbdd7cddefe3a1844e5c5913212f69875422d43b199cda692a15a6f76a74f7d5"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"b671db62ea723a21e11f69ba4b857e271573db22dd61aeb1d152b989824df5cb"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22276,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"55f52504ebcd3b4dc458ee4bbc99acb82aa3126f297a1101098130ad502cabb7"},{"bytes":1517603,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"ef7223d4be069f7e989a2c9e541f7cff510d46b3c126ceff5c907d666f87276b"},{"bytes":2382022,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"f563c98eb0a699dc9bcc787c2d6dfa59b32026cd3fd113ea399c047788c9316d"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1438250,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"7de9950e8f436024ef8bef47c406f7c4f720bd395de466a2593cb8fc6bdaa74b"},{"bytes":3264765,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b401a79c4f972b075d61602627f53472cdea0ebbb44e0995c49bbf0bbdcbacfe"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298594,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"2d6a8f6474f457729ad16d53810bea3098ecd94ee261e33b4eff60c3c879e74f"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"d0a620dd430c8ea389c97594c33d46a52acc58baa1bb85923ade99766c58b9da","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"2801fc8bb76c233d7ef0a7ba2d105ee662549c7d3def3caf521129751449e790","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"925703738114706c393a8cc7ac86ff3ac3159f359df312353551038f6d5aacfa","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"87d63f5b0bada3621036657c544f9d5345619add70040b4ec201760541ffae7a"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"5cdd948062f0ba15af16917870c74d77259ed97af008d15bce95095e246129c9"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"659483af940524ef155f505a0f4235ef76ed50a849a86fa1d7834256a0588838"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5ba4f07e35239c59cff2815eadb957fb13cf682d12bb25bf192f6bd8691eb4a5"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"14cd66c5b689ff9f587f7ca4eff32320903c7fb911f4306724141ceef7d9041a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"429ccecd068b34f7fb230a14f0b6ca662d2e5d61b6edc8d3fdfd54d91617d4ed"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"e72142dd6a4dfe49f103ca660f0dfe8a0a0df8759a8707d0a62cbad2b6df5c2c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"a33860336ea2c336d2f0a17168502f8dad37bce7de671ebc826a1652fd69c196"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"00a6c3f836e13e86bc8ffdcc621e3e360fe451e57d3c4af31f40a50bbd5ac65d"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"1bd8d2a4dba6d848331d5656c7e00649992435bcbd1f87903adc0a26179ebadf"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"143f138d886b4f20fa65bd61d01d01df19103cc386fffd3e331176e721a307e9"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"d260ca3a9d150900cc1a2e4f3df2e8f3712714ed9be2ecd6a646eda6e7b1b8d4"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"f2e1131e6f973fe8efb277022e77731196fbdaa226bede64ecfeae9eb0d0de2c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"f4d5e0377cdb7297754d3220c1935fc65bfb5f605b3bc0f15f5ff328f0ce3b63"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"5d7b69f5b0502039a086f1903951d735b02fb57107214b0f4d4d6abc349f352f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"521496fdfaff13cb55f4decb9e78ebaa1d2e35e7bfcc38cc887375b200724961"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"3de602b6e5ac42cfe0f2fe65a9c060a3d54bf8891eb8579538d412d7cfdb6c07"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"047c6bd900de50ae5ef8b1ac9391fdcaee5068af59f16cf1c2c3e23d0aea5385"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"dbdd7cddefe3a1844e5c5913212f69875422d43b199cda692a15a6f76a74f7d5"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"b671db62ea723a21e11f69ba4b857e271573db22dd61aeb1d152b989824df5cb"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22276,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"a872b8dca58bb1b0049ec0d53f322a145699a6fd55b1ec0ce5f98172d95cdf6e"},{"bytes":1517603,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"ef7223d4be069f7e989a2c9e541f7cff510d46b3c126ceff5c907d666f87276b"},{"bytes":2382022,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"f563c98eb0a699dc9bcc787c2d6dfa59b32026cd3fd113ea399c047788c9316d"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1438250,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"7de9950e8f436024ef8bef47c406f7c4f720bd395de466a2593cb8fc6bdaa74b"},{"bytes":3264765,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b401a79c4f972b075d61602627f53472cdea0ebbb44e0995c49bbf0bbdcbacfe"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298594,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"2d6a8f6474f457729ad16d53810bea3098ecd94ee261e33b4eff60c3c879e74f"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"d0a620dd430c8ea389c97594c33d46a52acc58baa1bb85923ade99766c58b9da","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} From 009ba7cff97e1e7b3a68cc4e23cbccdcd67a9614 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 28 Sep 2026 19:26:58 -0700 Subject: [PATCH 21/26] Exclude local plugin checkout from artifact source snapshots --- .gitignore | 3 +++ artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 18e51f5..94e82da 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ tmp-agents/ *.log .DS_Store *.tsbuildinfo + +# Local plugin checkout is not part of the shipped source snapshot. +/plugin/ diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 3437adb..0f816d5 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"ef7223d4be069f7e989a2c9e541f7cff510d46b3c126ceff5c907d666f87276b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"f563c98eb0a699dc9bcc787c2d6dfa59b32026cd3fd113ea399c047788c9316d"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"7de9950e8f436024ef8bef47c406f7c4f720bd395de466a2593cb8fc6bdaa74b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b401a79c4f972b075d61602627f53472cdea0ebbb44e0995c49bbf0bbdcbacfe"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"2d6a8f6474f457729ad16d53810bea3098ecd94ee261e33b4eff60c3c879e74f"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.4","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"ef7223d4be069f7e989a2c9e541f7cff510d46b3c126ceff5c907d666f87276b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"f563c98eb0a699dc9bcc787c2d6dfa59b32026cd3fd113ea399c047788c9316d"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"7de9950e8f436024ef8bef47c406f7c4f720bd395de466a2593cb8fc6bdaa74b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b401a79c4f972b075d61602627f53472cdea0ebbb44e0995c49bbf0bbdcbacfe"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"2d6a8f6474f457729ad16d53810bea3098ecd94ee261e33b4eff60c3c879e74f"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index b0c9ccb..e7d6a35 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"2801fc8bb76c233d7ef0a7ba2d105ee662549c7d3def3caf521129751449e790","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"925703738114706c393a8cc7ac86ff3ac3159f359df312353551038f6d5aacfa","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"3e8fdb390e0a40ebc680e14f015cfc607d92061f174dcea0c559ecad0da5058e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"87d63f5b0bada3621036657c544f9d5345619add70040b4ec201760541ffae7a"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"5cdd948062f0ba15af16917870c74d77259ed97af008d15bce95095e246129c9"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"659483af940524ef155f505a0f4235ef76ed50a849a86fa1d7834256a0588838"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5ba4f07e35239c59cff2815eadb957fb13cf682d12bb25bf192f6bd8691eb4a5"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"14cd66c5b689ff9f587f7ca4eff32320903c7fb911f4306724141ceef7d9041a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"429ccecd068b34f7fb230a14f0b6ca662d2e5d61b6edc8d3fdfd54d91617d4ed"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"e72142dd6a4dfe49f103ca660f0dfe8a0a0df8759a8707d0a62cbad2b6df5c2c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"a33860336ea2c336d2f0a17168502f8dad37bce7de671ebc826a1652fd69c196"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"00a6c3f836e13e86bc8ffdcc621e3e360fe451e57d3c4af31f40a50bbd5ac65d"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"1bd8d2a4dba6d848331d5656c7e00649992435bcbd1f87903adc0a26179ebadf"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"143f138d886b4f20fa65bd61d01d01df19103cc386fffd3e331176e721a307e9"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"d260ca3a9d150900cc1a2e4f3df2e8f3712714ed9be2ecd6a646eda6e7b1b8d4"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"f2e1131e6f973fe8efb277022e77731196fbdaa226bede64ecfeae9eb0d0de2c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"f4d5e0377cdb7297754d3220c1935fc65bfb5f605b3bc0f15f5ff328f0ce3b63"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"5d7b69f5b0502039a086f1903951d735b02fb57107214b0f4d4d6abc349f352f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"521496fdfaff13cb55f4decb9e78ebaa1d2e35e7bfcc38cc887375b200724961"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"3de602b6e5ac42cfe0f2fe65a9c060a3d54bf8891eb8579538d412d7cfdb6c07"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"047c6bd900de50ae5ef8b1ac9391fdcaee5068af59f16cf1c2c3e23d0aea5385"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"dbdd7cddefe3a1844e5c5913212f69875422d43b199cda692a15a6f76a74f7d5"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"b671db62ea723a21e11f69ba4b857e271573db22dd61aeb1d152b989824df5cb"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22276,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"a872b8dca58bb1b0049ec0d53f322a145699a6fd55b1ec0ce5f98172d95cdf6e"},{"bytes":1517603,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"ef7223d4be069f7e989a2c9e541f7cff510d46b3c126ceff5c907d666f87276b"},{"bytes":2382022,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"f563c98eb0a699dc9bcc787c2d6dfa59b32026cd3fd113ea399c047788c9316d"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1438250,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"7de9950e8f436024ef8bef47c406f7c4f720bd395de466a2593cb8fc6bdaa74b"},{"bytes":3264765,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b401a79c4f972b075d61602627f53472cdea0ebbb44e0995c49bbf0bbdcbacfe"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298594,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"2d6a8f6474f457729ad16d53810bea3098ecd94ee261e33b4eff60c3c879e74f"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"d0a620dd430c8ea389c97594c33d46a52acc58baa1bb85923ade99766c58b9da","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"2801fc8bb76c233d7ef0a7ba2d105ee662549c7d3def3caf521129751449e790","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"0bae738f27323ed2c4e14626f71abe341970da5efde9277efc06a1a0f1f8add2","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"30aaeac24084f0a642d811aa493fc51b0fd3eddff322d359c39c573d8394ff3e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"87d63f5b0bada3621036657c544f9d5345619add70040b4ec201760541ffae7a"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"5cdd948062f0ba15af16917870c74d77259ed97af008d15bce95095e246129c9"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"659483af940524ef155f505a0f4235ef76ed50a849a86fa1d7834256a0588838"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5ba4f07e35239c59cff2815eadb957fb13cf682d12bb25bf192f6bd8691eb4a5"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"14cd66c5b689ff9f587f7ca4eff32320903c7fb911f4306724141ceef7d9041a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"429ccecd068b34f7fb230a14f0b6ca662d2e5d61b6edc8d3fdfd54d91617d4ed"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"e72142dd6a4dfe49f103ca660f0dfe8a0a0df8759a8707d0a62cbad2b6df5c2c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"a33860336ea2c336d2f0a17168502f8dad37bce7de671ebc826a1652fd69c196"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"00a6c3f836e13e86bc8ffdcc621e3e360fe451e57d3c4af31f40a50bbd5ac65d"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"1bd8d2a4dba6d848331d5656c7e00649992435bcbd1f87903adc0a26179ebadf"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"143f138d886b4f20fa65bd61d01d01df19103cc386fffd3e331176e721a307e9"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"d260ca3a9d150900cc1a2e4f3df2e8f3712714ed9be2ecd6a646eda6e7b1b8d4"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"f2e1131e6f973fe8efb277022e77731196fbdaa226bede64ecfeae9eb0d0de2c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"f4d5e0377cdb7297754d3220c1935fc65bfb5f605b3bc0f15f5ff328f0ce3b63"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"5d7b69f5b0502039a086f1903951d735b02fb57107214b0f4d4d6abc349f352f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"521496fdfaff13cb55f4decb9e78ebaa1d2e35e7bfcc38cc887375b200724961"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"3de602b6e5ac42cfe0f2fe65a9c060a3d54bf8891eb8579538d412d7cfdb6c07"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"047c6bd900de50ae5ef8b1ac9391fdcaee5068af59f16cf1c2c3e23d0aea5385"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"dbdd7cddefe3a1844e5c5913212f69875422d43b199cda692a15a6f76a74f7d5"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"b671db62ea723a21e11f69ba4b857e271573db22dd61aeb1d152b989824df5cb"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22276,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"55f52504ebcd3b4dc458ee4bbc99acb82aa3126f297a1101098130ad502cabb7"},{"bytes":1517603,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"ef7223d4be069f7e989a2c9e541f7cff510d46b3c126ceff5c907d666f87276b"},{"bytes":2382022,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"f563c98eb0a699dc9bcc787c2d6dfa59b32026cd3fd113ea399c047788c9316d"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1438250,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"7de9950e8f436024ef8bef47c406f7c4f720bd395de466a2593cb8fc6bdaa74b"},{"bytes":3264765,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b401a79c4f972b075d61602627f53472cdea0ebbb44e0995c49bbf0bbdcbacfe"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298594,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"2d6a8f6474f457729ad16d53810bea3098ecd94ee261e33b4eff60c3c879e74f"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"d0a620dd430c8ea389c97594c33d46a52acc58baa1bb85923ade99766c58b9da","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} From 05c370c870ffd5fcd856dd85968fa6c39bed7694 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 28 Sep 2026 20:27:27 -0700 Subject: [PATCH 22/26] Fix ChatGPT Desktop e2e discovery and thread handling --- .changeset/desktop-e2e-reliability.md | 5 + artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 433 ++++++++++++++--- artifact/bin/gbot.mjs | 443 ++++++++++++++--- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 446 ++++++++++++++---- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 446 ++++++++++++++---- artifact/scripts/gbot-relay.mjs | 24 +- docs/chatgpt-desktop-cdp.md | 23 +- src/cli/chatgpt-desktop/read.tsx | 4 +- src/cli/chatgpt-desktop/threads.tsx | 4 +- src/core/chatgpt-desktop/adapter.ts | 1 + .../chatgpt-desktop/app-server-fallback.ts | 44 +- src/core/chatgpt-desktop/cdp-adapter.ts | 2 +- src/core/chatgpt-desktop/cdp-dom.ts | 95 +++- src/core/chatgpt-desktop/facade.ts | 129 +++-- src/core/chatgpt-desktop/remote-threads.ts | 29 +- src/core/chatgpt-desktop/routes.ts | 6 +- src/core/chatgpt-desktop/types.ts | 6 +- src/core/codex-bridge.js | 7 +- src/core/codex/remote-control.js | 16 +- .../tools/chatgpt_desktop_list_hosts.tsx | 2 +- .../tools/chatgpt_desktop_list_threads.tsx | 3 +- .../tools/chatgpt_desktop_read_thread.tsx | 4 +- test/codex-bridge.test.js | 2 +- .../chatgpt-desktop-e2e-regressions.test.ts | 255 ++++++++++ .../route-unit/chatgpt-desktop-review.test.ts | 7 +- tests/route-unit/chatgpt-desktop.test.ts | 17 +- 28 files changed, 2039 insertions(+), 418 deletions(-) create mode 100644 .changeset/desktop-e2e-reliability.md create mode 100644 tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts diff --git a/.changeset/desktop-e2e-reliability.md b/.changeset/desktop-e2e-reliability.md new file mode 100644 index 0000000..a4f7527 --- /dev/null +++ b/.changeset/desktop-e2e-reliability.md @@ -0,0 +1,5 @@ +--- +"grok-bot-cli": patch +--- + +Fix ChatGPT Desktop host discovery, bounded thread reads and searches, list pagination, CDP navigation and project clicks, status reachability, and result provenance. diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 0f816d5..97e1959 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"ef7223d4be069f7e989a2c9e541f7cff510d46b3c126ceff5c907d666f87276b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"f563c98eb0a699dc9bcc787c2d6dfa59b32026cd3fd113ea399c047788c9316d"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"7de9950e8f436024ef8bef47c406f7c4f720bd395de466a2593cb8fc6bdaa74b"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b401a79c4f972b075d61602627f53472cdea0ebbb44e0995c49bbf0bbdcbacfe"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"2d6a8f6474f457729ad16d53810bea3098ecd94ee261e33b4eff60c3c879e74f"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"b232ed66e778ef4abba677ef20f60d1c47a834ab3741e526a38ced3b2098b126"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"eaf64010acbeac8278b2f8ba77977cabf96ef0b4bc2c52c7cacf6d41010a870b"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"abb8db232326732759af2a555de555cd1af4beebeb082c5ebca214ff2fc713f3"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"9c8bbfa57c9937aed83ee0c3efecaf970cb41d24db3d7fb135d2b33d24d63677"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"4c189f7e866020f7e9265ce684da2d47a0f75feabc9a5c1d6f60098c31924064"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index e7d6a35..42860ba 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"2801fc8bb76c233d7ef0a7ba2d105ee662549c7d3def3caf521129751449e790","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"0bae738f27323ed2c4e14626f71abe341970da5efde9277efc06a1a0f1f8add2","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"30aaeac24084f0a642d811aa493fc51b0fd3eddff322d359c39c573d8394ff3e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"87d63f5b0bada3621036657c544f9d5345619add70040b4ec201760541ffae7a"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"165d11662b69271fe281dcae8dbb8df67eb66bf3119ca4434bb6a5e657901a52"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"5cdd948062f0ba15af16917870c74d77259ed97af008d15bce95095e246129c9"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"659483af940524ef155f505a0f4235ef76ed50a849a86fa1d7834256a0588838"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5ba4f07e35239c59cff2815eadb957fb13cf682d12bb25bf192f6bd8691eb4a5"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"14cd66c5b689ff9f587f7ca4eff32320903c7fb911f4306724141ceef7d9041a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"429ccecd068b34f7fb230a14f0b6ca662d2e5d61b6edc8d3fdfd54d91617d4ed"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"e72142dd6a4dfe49f103ca660f0dfe8a0a0df8759a8707d0a62cbad2b6df5c2c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"a33860336ea2c336d2f0a17168502f8dad37bce7de671ebc826a1652fd69c196"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"00a6c3f836e13e86bc8ffdcc621e3e360fe451e57d3c4af31f40a50bbd5ac65d"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"1bd8d2a4dba6d848331d5656c7e00649992435bcbd1f87903adc0a26179ebadf"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"143f138d886b4f20fa65bd61d01d01df19103cc386fffd3e331176e721a307e9"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"d260ca3a9d150900cc1a2e4f3df2e8f3712714ed9be2ecd6a646eda6e7b1b8d4"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"f2e1131e6f973fe8efb277022e77731196fbdaa226bede64ecfeae9eb0d0de2c"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"9e7d242981e688dd05f1622eae90dddcc9d2167737a18c4e603d842e5f1cd4d1"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"f4d5e0377cdb7297754d3220c1935fc65bfb5f605b3bc0f15f5ff328f0ce3b63"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"5d7b69f5b0502039a086f1903951d735b02fb57107214b0f4d4d6abc349f352f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"521496fdfaff13cb55f4decb9e78ebaa1d2e35e7bfcc38cc887375b200724961"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"e796edd32173ef52e6b7ffdd5e6f4aa4b99b78e6b883bf5eb40823352bb60525"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"3de602b6e5ac42cfe0f2fe65a9c060a3d54bf8891eb8579538d412d7cfdb6c07"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"047c6bd900de50ae5ef8b1ac9391fdcaee5068af59f16cf1c2c3e23d0aea5385"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"dbdd7cddefe3a1844e5c5913212f69875422d43b199cda692a15a6f76a74f7d5"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"b671db62ea723a21e11f69ba4b857e271573db22dd61aeb1d152b989824df5cb"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22276,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"55f52504ebcd3b4dc458ee4bbc99acb82aa3126f297a1101098130ad502cabb7"},{"bytes":1517603,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"ef7223d4be069f7e989a2c9e541f7cff510d46b3c126ceff5c907d666f87276b"},{"bytes":2382022,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"f563c98eb0a699dc9bcc787c2d6dfa59b32026cd3fd113ea399c047788c9316d"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1438250,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"7de9950e8f436024ef8bef47c406f7c4f720bd395de466a2593cb8fc6bdaa74b"},{"bytes":3264765,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"b401a79c4f972b075d61602627f53472cdea0ebbb44e0995c49bbf0bbdcbacfe"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1298594,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"2d6a8f6474f457729ad16d53810bea3098ecd94ee261e33b4eff60c3c879e74f"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"default":100,"type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"d0a620dd430c8ea389c97594c33d46a52acc58baa1bb85923ade99766c58b9da","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"04cadea34351c5aa9b548241ec2a0dd7e47ca671cb716cb2a39a43198aa5d48b","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"61cd412ae47654cc8536e53abfa87cab5c51c9e3d844f97aaab595bd0796c6e1","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/desktop-e2e-reliability.md","sha256":"6fee865161991ceca89a10e49f4721326257bb03ff431c1016cf23e2319318b3"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"30aaeac24084f0a642d811aa493fc51b0fd3eddff322d359c39c573d8394ff3e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"4e11165ccdca7507a643e7670a56e9dcbdfb77305b4d33bd12c6008513349426"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"a322d4cfa34f3a2603c4233c13a8e47be4b939bc5d4d9dff46a757b2289665dc"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"5cdd948062f0ba15af16917870c74d77259ed97af008d15bce95095e246129c9"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"0a70d4937c6ffc19397adedd301c19d973592f0a97347cd7e53d855b35ac556c"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"8c62b1750a8864f8c6d95ea1ce724b94a77b08de2dc4a052e1b8d6e935966485"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"a5414d9209bf529323dcc399c1bacf6287689f9bed5158239136305bd928949d"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"a71de63de0a5d9921263262958960a6ea2032864f82d41ccff3aa374c6598799"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"1a3610381f04a8b0f231466229e5bf0628bc9f7b7f794e5d1dcb4bb4515983fd"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"a33860336ea2c336d2f0a17168502f8dad37bce7de671ebc826a1652fd69c196"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"23f6f428693da5c3e638050ab97289ff48333a0be1874f425a837f1f28a21bd8"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"ed93418ff5d2bb51016783e7b0a458805e709b212974a66be804ddb9f7038033"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"55cc7b6ccd125894bf52ddc00fa5bae044227088594d0711333de0e736ec8ea2"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"ca0eb69a76895840fb8c84ed5e75d27d8a26a09c61158ea364882b4dcf060878"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"d398fd4a1ecff32c58084a9e1c6266e8f6cf2db7ef29777a44d43e2ef0196ddd"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"52565007799e98c3bff4297287d8e53005e285a95bab9e4e4d0a088bded4fa8e"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"f4d5e0377cdb7297754d3220c1935fc65bfb5f605b3bc0f15f5ff328f0ce3b63"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"30af9ffb3e8ed8679c3c290f3d75bd54825f9d9cdaec9e22e10b6fd2f84817c1"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"b0fbcdb613dd9d8410ea9eb96dae8b5b8a9633e4c813bc9cff24b8355de1c0fd"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"04fbbcaf2b52cbdb0aef156429a5be2a66c950767c1d6d68cbf472fa92380bff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"cdeb0f18c938e13facf467c1b4364394ed799c87b2d4b4566508c527efc6bef4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts","sha256":"85bd7fdfcc0c6b52deb796f97897b07edc03e0a9d5669b323341f33db42c096c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"208dfdea18ccc408a279666a521d2f70fdce9bdaf28f86bc5d053f7ad09a7dd2"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"810be6a2ec5ec02295f373e2a335b9a38d49d354832e6a707bb45b88f90a3c9d"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"b671db62ea723a21e11f69ba4b857e271573db22dd61aeb1d152b989824df5cb"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22276,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"ab45c9b3ef6e5a79e8da9e13ae8a57d8dfb9269f120ec4dc850578f80fa0cd93"},{"bytes":1533419,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"b232ed66e778ef4abba677ef20f60d1c47a834ab3741e526a38ced3b2098b126"},{"bytes":2398279,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"eaf64010acbeac8278b2f8ba77977cabf96ef0b4bc2c52c7cacf6d41010a870b"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1453666,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"abb8db232326732759af2a555de555cd1af4beebeb082c5ebca214ff2fc713f3"},{"bytes":3280217,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"9c8bbfa57c9937aed83ee0c3efecaf970cb41d24db3d7fb135d2b33d24d63677"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1299066,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"4c189f7e866020f7e9265ce684da2d47a0f75feabc9a5c1d6f60098c31924064"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Recent default 100; full default 2000","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a previous page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"07eaaacda7d8c988d5bc2fd40cdfec2a80980d0cc7491b6b626391207cbed0bb","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover local, remote-control, and managed SSH hosts from Desktop state, including nested remote-thread summaries. Host names are null when Desktop has no display name. Providers come from paged app-server inventory and remote summaries. Result includes sources and discovery warnings.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"Page ChatGPT Desktop / Codex threads with cursor and nextCursor. Merges local app-server rows, CDP sidebar rows, and nested remote-control summaries. Discover dynamic host and modelProvider filters via chatgpt_desktop_list_hosts. Optional groupBy=host. Result reports the contributing backends and warnings.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read paged ChatGPT Desktop turns through app-server, including userText, assistantText, and completedAt as endedAt. Remote-only threads return REMOTE_THREAD_NOT_LOADED with hostId. CDP fallback reports complete:false and a warning when app-server fails. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index b655a49..22bf562 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -8675,7 +8675,7 @@ var __webpack_modules__ = { type: 'boolean' }, limit: { - default: 100, + description: 'Recent default 100; full default 2000', type: 'number' }, openTimeoutMs: { @@ -8700,7 +8700,7 @@ var __webpack_modules__ = { }; const inputSchema = zod__rspack_import_2.Ikc({ full: zod__rspack_import_2.zMY().default(false), - limit: zod__rspack_import_2.aig().int().min(1).max(2000).default(100), + limit: zod__rspack_import_2.aig().int().min(1).max(2000).optional(), openTimeoutMs: zod__rspack_import_2.aig().int().min(1).max(600000).default(90000), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), threadId: zod__rspack_import_2.YjP().min(1).max(256) @@ -8946,6 +8946,10 @@ var __webpack_modules__ = { description: 'Max threads (1-200)', type: 'number' }, + cursor: { + description: 'Opaque nextCursor from a previous page', + type: 'string' + }, modelProvider: { description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' @@ -8962,6 +8966,7 @@ var __webpack_modules__ = { groupBy: zod__rspack_import_2.euz('host').optional(), host: zod__rspack_import_2.YjP().min(1).max(256).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), + cursor: zod__rspack_import_2.YjP().min(1).max(4096).optional(), modelProvider: zod__rspack_import_2.YjP().min(1).max(256).optional(), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() }).strict(); @@ -8973,7 +8978,7 @@ var __webpack_modules__ = { const where = row.location === 'remote' ? ` [remote ${row.hostName || row.hostId || '?'}]` : ' [local]'; const provider = row.modelProvider ? ` {${row.modelProvider}}` : ''; return `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : '') + where + provider; - }).join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); + }).join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` + (out.nextCursor ? `\nnextCursor: ${out.nextCursor}` : '') : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { value: out, children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { @@ -11298,9 +11303,10 @@ var __webpack_modules__ = { } const matched = []; let cursor; - for(let page = 0; page < 20 && matched.length < limit; page++){ + let exhausted = false; + for(let page = 0; page < 400 && matched.length < limit; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit: 200, + limit: 25, cursor, modelProviders }); @@ -11309,7 +11315,10 @@ var __webpack_modules__ = { if (threadMatchesQuery(mapped, needle)) matched.push(mapped); if (matched.length >= limit) break; } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + if (out.nextCursor == null || typeof out.nextCursor !== 'string') { + exhausted = true; + break; + } cursor = out.nextCursor; } return { @@ -11318,34 +11327,48 @@ var __webpack_modules__ = { query, nextCursor: null, threads: matched.slice(0, limit), - modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, + ...!exhausted && matched.length < limit ? { + warnings: [ + 'Search stopped after 400 app-server pages; results may be incomplete' + ] + } : {} }; } async function discoverModelProviders() { const providers = new Set(); + let threadCount = 0; let cursor; - for(let page = 0; page < 20; page++){ + let complete = false; + for(let page = 0; page < 400; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit: 200, + limit: 25, cursor, modelProviders: [] }); + threadCount += out.threads.length; for (const thread of out.threads){ if (typeof thread.modelProvider === 'string' && thread.modelProvider) { providers.add(thread.modelProvider); } } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + if (out.nextCursor == null || typeof out.nextCursor !== 'string') { + complete = true; + break; + } cursor = out.nextCursor; } return { providers: [ ...providers ].sort(), - source: 'thread/list-distinct' + source: 'thread/list-distinct', + threadCount, + complete }; } - async function appServerReadThread({ threadId, limit = 100, full = false }) { + async function appServerReadThread({ threadId, limit, full = false }) { + limit ??= full ? 2000 : 100; const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); if (remote) { @@ -11374,7 +11397,7 @@ var __webpack_modules__ = { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { const meta = await readThreadMetadata(client, bare); - const turns = await listTurnsFull(client, bare, { + const { turns, complete } = await listTurnsFull(client, bare, { limit, full }); @@ -11384,6 +11407,7 @@ var __webpack_modules__ = { backend: 'app-server', limit, full, + complete, title: meta.title, cwd: meta.cwd, status: meta.status, @@ -11472,12 +11496,13 @@ var __webpack_modules__ = { let itemsView = true; let method = 'thread/turns/list'; const seen = new Set(); + let complete = false; while(collected.length < limit){ let result; try { result = await client.request(method, { threadId, - limit: Math.min(100, limit - collected.length), + limit: Math.min(10, limit - collected.length), sortDirection: full ? 'asc' : 'desc', ...method === 'thread/turns/list' && itemsView ? { itemsView: 'full' @@ -11500,7 +11525,10 @@ var __webpack_modules__ = { } if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); collected.push(...result.data); - if (result.nextCursor == null) break; + if (result.nextCursor == null) { + complete = true; + break; + } if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { throw new Error(`${method} returned an invalid or repeated cursor`); } @@ -11508,7 +11536,10 @@ var __webpack_modules__ = { cursor = result.nextCursor; } const turns = normalizeTurns(collected.slice(0, limit)); - return full ? turns : turns.reverse(); + return { + turns: full ? turns : turns.reverse(), + complete + }; } function normalizeTurns(raw) { const turns = []; @@ -11564,7 +11595,7 @@ var __webpack_modules__ = { assistantText } : {}, startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, - endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + endedAt: typeof row.completedAt === 'number' ? row.completedAt : typeof row.endedAt === 'number' ? row.endedAt : null }; } function normalizeLeafItem(id, row) { @@ -11580,12 +11611,13 @@ var __webpack_modules__ = { role, text, startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, - endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + endedAt: typeof row.completedAt === 'number' ? row.completedAt : typeof row.endedAt === 'number' ? row.endedAt : null }; } function extractText(row) { if (typeof row.text === 'string') return row.text; if (typeof row.content === 'string') return row.content; + if (Array.isArray(row.content)) return row.content.filter((part)=>Boolean(part) && typeof part === 'object' && !Array.isArray(part)).map((part)=>typeof part.text === 'string' ? part.text : '').filter(Boolean).join('\n'); if (typeof row.preview === 'string') return row.preview; return ''; } @@ -11692,7 +11724,8 @@ var __webpack_modules__ = { turns, backend: 'cdp', limit, - full + full, + complete: false }; } async sendMessage({ threadId, text, project, openTimeoutMs = 90000 }) { @@ -12006,6 +12039,7 @@ var __webpack_modules__ = { const project = projectFor(row); out.push({ threadId, + hostId: row.getAttribute('data-app-action-sidebar-thread-host-id') || null, title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', @@ -12034,6 +12068,26 @@ var __webpack_modules__ = { if (!row) return { ok: false, error: 'thread-not-found' }; row.click(); return { ok: true, threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || candidates[0] }; + })()`; + } + function navigateToThreadExpression(threadId) { + const bare = durableThreadKey(threadId); + return `(async () => { + const root = window.__codexRoot?._internalRoot?.current; + const queue = [root]; + let scanned = 0; + while (queue.length && scanned++ < 10000) { + const fiber = queue.shift(); + if (!fiber) continue; + const router = fiber.memoizedProps?.router; + if (router?.navigate && router?.state?.location) { + await router.navigate(${JSON.stringify(`/local/${bare}`)}); + return { ok: true, via: 'router' }; + } + if (fiber.child) queue.push(fiber.child); + if (fiber.sibling) queue.push(fiber.sibling); + } + return { ok: false, error: 'router-not-found' }; })()`; } function startNewChatExpression(project) { @@ -12043,8 +12097,11 @@ var __webpack_modules__ = { if (projectSel) { const preferred = document.querySelector(projectSel); if (preferred) { - preferred.click(); - return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; + const row = preferred.closest('.group') || preferred.parentElement; + row?.scrollIntoView({ block: 'center' }); + const rowBox = row?.getBoundingClientRect(); + return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)}, + hoverX: rowBox?.left + rowBox?.width / 2, hoverY: rowBox?.top + rowBox?.height / 2 }; } return { ok: false, error: 'project-not-found' }; } @@ -12053,6 +12110,15 @@ var __webpack_modules__ = { if (!fallback) return { ok: false, error: 'new-chat-not-found' }; fallback.click(); return { ok: true, via: 'fallback' }; + })()`; + } + function projectButtonBoxExpression(project) { + return `(() => { + const button = document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); + if (!button) return null; + const box = button.getBoundingClientRect(); + return { x: box.left + box.width / 2, y: box.top + box.height / 2, + visible: box.width > 0 && box.height > 0 && getComputedStyle(button.parentElement).opacity !== '0' }; })()`; } const LOADING_TASK_GONE_EXPRESSION = `(() => { @@ -12066,6 +12132,9 @@ var __webpack_modules__ = { const text = (surface.innerText || '').replace(/\\u2026/g, '…'); return !text.includes(${JSON.stringify(LOADING_TASK_TEXT)}); })()`; + const ARCHIVED_THREAD_EXPRESSION = `(() => Array.from(document.querySelectorAll('main')) + .some((main) => (main.innerText || '').includes('This task is archived') + && (main.innerText || '').includes('Unarchive this task to open it')))()`; const FOCUS_COMPOSER_EXPRESSION = `(() => { const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); if (!composer) return { ok: false, error: 'composer-not-found' }; @@ -12170,27 +12239,60 @@ var __webpack_modules__ = { pinned: Boolean(row.pinned), selected: Boolean(row.selected), kind: String(row.kind ?? 'unknown'), + ...row.hostId ? { + hostId: row.hostId, + location: row.hostId === 'local' ? 'local' : 'remote' + } : {}, ...row.project ? { project: String(row.project) } : {} })); } async function openThreadInDom(session, sessionId, threadId) { + const current = await readConversationIdFromDom(session, sessionId); + if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; + if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + const rows = await listThreadsFromDom(session, sessionId, { + limit: 200 + }); + if (rows.some((row)=>row.selected && row.threadId === threadId)) return; + } const result = await session.evaluate(openThreadExpression(threadId), { sessionId }); if (!result?.ok) { + if (result?.error === 'thread-not-found' && !(0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + const navigated = await session.evaluate(navigateToThreadExpression(threadId), { + sessionId + }); + if (navigated?.ok) return; + } throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); } } async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS, threadId } = {}) { const deadline = Date.now() + timeoutMs; + let loadingGone = false; + let lastConversationId = ''; + let archivedSince = null; while(Date.now() < deadline){ + if (threadId && threadId !== 'new' && await session.evaluate(ARCHIVED_THREAD_EXPRESSION, { + sessionId + }) === true) { + archivedSince ??= Date.now(); + if (Date.now() - archivedSince >= 500) { + throw new Error(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived; unarchive it in Desktop before opening`); + } + } else { + archivedSince = null; + } const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { sessionId }); + loadingGone ||= gone; if (gone) { const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; + lastConversationId = current; if (!threadId) return; if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { @@ -12202,7 +12304,7 @@ var __webpack_modules__ = { } await delay(250); } - throw new Error(`ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); + throw new Error(loadingGone ? `ChatGPT Desktop timed out waiting for conversation ${JSON.stringify(threadId)}; displayed conversation ${JSON.stringify(lastConversationId)} after ${timeoutMs}ms` : `ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); } async function startNewChatInDom(session, sessionId, { project } = {}) { const result = await session.evaluate(startNewChatExpression(project), { @@ -12211,6 +12313,52 @@ var __webpack_modules__ = { if (!result?.ok) { throw new Error(project ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` : 'ChatGPT Desktop "New chat" button not found'); } + if (result.via === 'project') { + if (![ + result.hoverX, + result.hoverY + ].every(Number.isFinite)) { + throw new Error(`ChatGPT Desktop project button has no visible box for ${JSON.stringify(project)}`); + } + await session.send('Input.dispatchMouseEvent', { + type: 'mouseMoved', + x: result.hoverX, + y: result.hoverY + }, { + sessionId + }); + const button = await session.evaluate(projectButtonBoxExpression(project), { + sessionId + }); + if (!button?.visible || !Number.isFinite(button.x) || !Number.isFinite(button.y)) { + throw new Error(`ChatGPT Desktop project button did not appear after hover for ${JSON.stringify(project)}`); + } + await session.send('Input.dispatchMouseEvent', { + type: 'mouseMoved', + x: button.x, + y: button.y + }, { + sessionId + }); + await session.send('Input.dispatchMouseEvent', { + type: 'mousePressed', + x: button.x, + y: button.y, + button: 'left', + clickCount: 1 + }, { + sessionId + }); + await session.send('Input.dispatchMouseEvent', { + type: 'mouseReleased', + x: button.x, + y: button.y, + button: 'left', + clickCount: 1 + }, { + sessionId + }); + } return { via: result.via ?? 'unknown' }; @@ -12357,16 +12505,18 @@ var __webpack_modules__ = { } async function readTurnsFromDom(session, sessionId, { limit = 100, full = false, threadId, idleWheels = DEFAULT_FULL_READ_IDLE_WHEELS, maxWheels = DEFAULT_FULL_READ_MAX_WHEELS } = {}) { const collected = new Map(); + const order = []; const ingest = async ()=>{ + const older = []; for (const turn of (await harvestVisibleTurns(session, sessionId))){ + if (!collected.has(turn.turnKey)) older.push(turn.turnKey); collected.set(turn.turnKey, turn); } + order.unshift(...older); }; await ingest(); if (!full) { - const visible = [ - ...collected.values() - ]; + const visible = order.map((key)=>collected.get(key)); return limit > 0 ? visible.slice(-limit) : visible; } let idle = 0; @@ -12395,9 +12545,7 @@ var __webpack_modules__ = { } if (threadId && collected.has(threadId)) break; } - const all = [ - ...collected.values() - ]; + const all = order.map((key)=>collected.get(key)); return limit > 0 ? all.slice(0, limit) : all; } function delay(ms) { @@ -12667,6 +12815,8 @@ var __webpack_modules__ = { listHosts: _remote_threads_js__rspack_import_4.Kl, discoverModelProviders: _app_server_fallback_js__rspack_import_1.X }; + const REMOTE_PAGE_CURSOR = 'desktop-remote-page:'; + const APP_START_CURSOR = 'desktop-app-start'; class ChatGptDesktopFacade { #cdp; #port; @@ -12697,23 +12847,21 @@ var __webpack_modules__ = { const limit = options.limit ?? 50; const host = normalizeHostFilter(options.host); const modelProviders = modelProvidersFromFilter(options.modelProvider); - let appList = null; - let appError; - try { - appList = await this.#fallbacks.listThreads({ - limit, - modelProviders - }); - } catch (error) { - appError = error; + const remoteOffset = options.cursor?.startsWith(REMOTE_PAGE_CURSOR) ? Number(options.cursor.slice(REMOTE_PAGE_CURSOR.length)) : null; + if (remoteOffset !== null && (!Number.isSafeInteger(remoteOffset) || remoteOffset < 1)) { + throw new Error('Invalid ChatGPT Desktop remote page cursor'); } + const inventoryPage = !options.cursor || remoteOffset !== null; + const remotes = inventoryPage ? this.#listRemotes() : []; let cdpList = null; let cdpError; try { - await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads({ - limit - }); + if (inventoryPage) { + await this.#ensureCdp(); + cdpList = await this.#cdp.listThreads({ + limit: 200 + }); + } } catch (error) { if (isCdpFailure(error)) { this.#cdpConnected = false; @@ -12721,33 +12869,87 @@ var __webpack_modules__ = { cdpError = error; } } - const remotes = this.#listRemotes(); + if (inventoryPage && host !== 'local') { + const remoteInventory = finalizeThreadList({ + backend: cdpList?.backend ?? 'remote-state', + limit: 10000, + threads: cdpList?.threads.filter((thread)=>thread.location === 'remote') ?? [] + }, { + limit: 10000, + host, + modelProvider: options.modelProvider, + remotes + }); + const offset = remoteOffset ?? 0; + if (remoteOffset !== null || remoteInventory.threads.length >= limit) { + const page = remoteInventory.threads.slice(offset, offset + limit); + const nextOffset = offset + page.length; + const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; + return { + ...remoteInventory, + threads: page, + limit, + nextCursor, + ...options.groupBy === 'host' ? { + groupBy: 'host', + groups: groupThreadsByHost(page) + } : {} + }; + } + } + const remoteKeys = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; + const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); + let appList = null; + let appError; + try { + appList = await this.#fallbacks.listThreads({ + limit: appLimit, + cursor: options.cursor === APP_START_CURSOR ? undefined : options.cursor, + modelProviders + }); + } catch (error) { + appError = error; + } let base = null; if (appList && cdpList) base = mergeThreadLists(appList, cdpList); else if (appList) base = appList; else if (cdpList) base = cdpList; else if (remotes.length) base = { - backend: 'app-server', + backend: 'remote-state', limit, threads: [] }; else if (cdpError) throw cdpError; else if (appError) throw appError; else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); - return finalizeThreadList(base, { + const result = finalizeThreadList(base, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes }); + const withCursor = host === 'all' || host === 'local' ? result : { + ...result, + nextCursor: null + }; + return appError ? { + ...withCursor, + warnings: [ + `App-server list failed: ${appError instanceof Error ? appError.message : String(appError)}` + ] + } : withCursor; } async listHosts() { const remotes = this.#listRemotes(); + const cdpRows = typeof this.#cdp.listThreads === 'function' ? (await this.#tryCdpList({ + limit: 200 + }))?.threads ?? [] : []; let localThreadCount = 0; try { const local = await this.#fallbacks.listThreads({ - limit: 200, + limit: 25, modelProviders: [] }); localThreadCount = local.threads.length; @@ -12780,11 +12982,28 @@ var __webpack_modules__ = { }); } } - const hostsSource = 'remote-thread-summaries-v3+local'; + for (const thread of cdpRows){ + if (thread.location !== 'remote' || !thread.hostId) continue; + if (!byId.has(thread.hostId)) byId.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName ?? null, + location: 'remote', + threadCount: 0 + }); + } + const hostsSource = 'local+remote-thread-summaries-v3+managed-connections' + (cdpRows.length ? '+cdp' : ''); const remoteCounts = new Map(); for (const thread of remotes){ remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); } + const remoteIds = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + for (const thread of cdpRows){ + if (thread.location !== 'remote' || !thread.hostId) continue; + const id = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; + if (remoteIds.has(id)) continue; + remoteIds.add(id); + remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + } const withCounts = [ ...byId.values() ].map((host)=>host.hostId === 'local' ? { @@ -12800,6 +13019,7 @@ var __webpack_modules__ = { }); let modelProviders = []; let modelProvidersSource = 'thread/list-distinct'; + const warnings = []; try { const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_1.X; const discovered = await discover(); @@ -12807,7 +13027,10 @@ var __webpack_modules__ = { ...discovered.providers ]; modelProvidersSource = discovered.source; - } catch { + if (typeof discovered.threadCount === 'number') localThreadCount = discovered.threadCount; + if (discovered.complete === false) warnings.push('Provider discovery stopped before the final app-server page'); + } catch (error) { + warnings.push(`Model provider discovery failed: ${error instanceof Error ? error.message : String(error)}`); modelProviders = [ ...new Set(remotes.map((thread)=>thread.modelProvider).filter((value)=>typeof value === 'string' && Boolean(value))) ].sort(); @@ -12820,11 +13043,17 @@ var __webpack_modules__ = { ]) ].sort(); return { - hosts: withCounts, + hosts: withCounts.map((host)=>host.hostId === 'local' ? { + ...host, + threadCount: localThreadCount + } : host), hostsSource, modelProviders, modelProvidersSource, - backend: 'app-server' + backend: cdpRows.length ? remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp' : remotes.length ? 'app-server+remote-state' : 'app-server', + ...warnings.length ? { + warnings + } : {} }; } async searchThreads(options) { @@ -12853,13 +13082,14 @@ var __webpack_modules__ = { query: options.query, threads: withRemotes.threads.filter((thread)=>threadMatchesQuery(thread, needle)) }; - return finalizeThreadList(filtered, { + const result = finalizeThreadList(filtered, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: [] }); + return result; } catch (appError) { const cdpList = await this.#tryCdpList({ limit @@ -12875,17 +13105,23 @@ var __webpack_modules__ = { query: options.query, threads: (cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) }; - return finalizeThreadList(filtered, { + const result = finalizeThreadList(filtered, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) }); + return { + ...result, + warnings: [ + `App-server search failed: ${appError instanceof Error ? appError.message : String(appError)}` + ] + }; } } async readThread(options) { - const limit = options.limit ?? 100; + const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { await this.#ensureCdp(); @@ -12905,11 +13141,18 @@ var __webpack_modules__ = { if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; - return this.#cdp.readThread({ + const fallback = await this.#cdp.readThread({ ...options, limit, full }); + return { + ...fallback, + complete: false, + warnings: [ + `App-server read failed: ${appError instanceof Error ? appError.message : String(appError)}` + ] + }; } } async sendMessage(options) { @@ -12934,13 +13177,13 @@ var __webpack_modules__ = { reachable: false }; } - const reachable = cdpStatus.reachable || Boolean(appServerFallback?.reachable); + const reachable = cdpStatus.reachable; return { ...cdpStatus, port: this.#port, appServerFallback, reachable, - message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/search/read' : cdpStatus.message, + message: cdpStatus.reachable ? cdpStatus.message : cdpStatus.message, exitCode: reachable ? 0 : 1 }; } @@ -13008,7 +13251,10 @@ var __webpack_modules__ = { pinned: withLocal.pinned || cdp.pinned, selected: cdp.selected, kind: cdp.kind || withLocal.kind, - project: cdp.project ?? withLocal.project + project: cdp.project ?? withLocal.project, + location: cdp.location === 'remote' ? 'remote' : withLocal.location, + hostId: cdp.location === 'remote' ? cdp.hostId ?? null : withLocal.hostId, + hostName: cdp.location === 'remote' ? cdp.hostName ?? null : withLocal.hostName }; }); for (const thread of cdpList.threads){ @@ -13016,7 +13262,7 @@ var __webpack_modules__ = { merged.push(thread); } return { - backend: appList.backend, + backend: 'app-server+cdp', limit: appList.limit, nextCursor: appList.nextCursor, ...appList.query !== undefined ? { @@ -13032,7 +13278,7 @@ var __webpack_modules__ = { ])); const locals = base.threads.map((thread)=>{ const remote = remoteById.get((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId); - if (remote && thread.location === undefined) { + if (remote) { return { ...thread, ...remote, @@ -13062,6 +13308,7 @@ var __webpack_modules__ = { hostName: remote.hostName ?? null }); } + if (remotes.length) merged.sort((a, b)=>Number(b.location === 'remote') - Number(a.location === 'remote')); const filtered = merged.filter((thread)=>{ if (!hostMatches(thread, host)) return false; if (!modelProviderMatches(thread, modelProvider)) return false; @@ -13069,7 +13316,7 @@ var __webpack_modules__ = { }); const limited = filtered.slice(0, limit); const result = { - backend: base.backend, + backend: remotes.length ? base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' : base.backend === 'app-server' ? 'app-server+remote-state' : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend : base.backend, limit, threads: limited, ...base.nextCursor !== undefined ? { @@ -13242,7 +13489,7 @@ var __webpack_modules__ = { const hostNames = collectHostNames(data); const out = []; const seen = new Set(); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of (0, _codex_remote_control_js__rspack_import_0.xr)(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; @@ -13294,12 +13541,12 @@ var __webpack_modules__ = { const data = (0, _codex_remote_control_js__rspack_import_0.IT)(env); if (data) { const hostNames = collectHostNames(data); - for (const key of Object.keys(data)){ + for (const [key, summary] of (0, _codex_remote_control_js__rspack_import_0.xr)(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; - const summary = data[key]; const hostName = hostNames.get(hostId) ?? extractHostName(summary) ?? null; + if (byHost.has(hostId)) continue; byHost.set(hostId, { hostId, hostName, @@ -13307,6 +13554,22 @@ var __webpack_modules__ = { threadCount: 0 }); } + const connections = data['codex-managed-remote-connections']; + if (Array.isArray(connections)) for (const entry of connections){ + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) continue; + const hostId = stringField(entry, [ + 'hostId' + ]); + if (hostId && !byHost.has(hostId)) byHost.set(hostId, { + hostId, + hostName: stringField(entry, [ + 'displayName', + 'alias' + ]), + location: 'remote', + threadCount: 0 + }); + } } for (const thread of remotes){ const existing = byHost.get(thread.hostId); @@ -13335,20 +13598,25 @@ var __webpack_modules__ = { } function collectHostNames(data) { const names = new Map(); - for (const [key, value] of Object.entries(data)){ + const connections = data['codex-managed-remote-connections']; + if (Array.isArray(connections)) for (const entry of connections){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + for (const [key, value] of (0, _codex_remote_control_js__rspack_import_0.xr)(data).flatMap(Object.entries)){ if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; if (!value || typeof value !== 'object') continue; if (Array.isArray(value)) { for (const entry of value){ const pair = hostNameFromEntry(entry); - if (pair) names.set(pair.hostId, pair.hostName); + if (pair && !names.has(pair.hostId)) names.set(pair.hostId, pair.hostName); } continue; } for (const [hostId, entry] of Object.entries(value)){ const fromEntry = hostNameFromEntry(entry); if (fromEntry) { - names.set(fromEntry.hostId, fromEntry.hostName); + if (!names.has(fromEntry.hostId)) names.set(fromEntry.hostId, fromEntry.hostName); continue; } const label = stringField(entry, [ @@ -13359,7 +13627,7 @@ var __webpack_modules__ = { 'label', 'title' ]); - if (label) names.set(hostId, label); + if (label && !names.has(hostId)) names.set(hostId, label); } } return names; @@ -13638,6 +13906,7 @@ var __webpack_modules__ = { const listThreadsSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() @@ -13656,7 +13925,7 @@ var __webpack_modules__ = { const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, - limit: zod__rspack_import_4.aig().int().min(1).max(2000).default(100), + limit: zod__rspack_import_4.aig().int().min(1).max(2000).optional(), full: zod__rspack_import_4.zMY().default(false), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); @@ -13748,6 +14017,7 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ limit: input.limit, + cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, groupBy: input.groupBy @@ -13802,7 +14072,7 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ threadId: input.threadId, - limit: input.limit, + limit: input.limit ?? (input.full ? 2000 : 100), full: input.full, openTimeoutMs: input.openTimeoutMs })); @@ -24856,8 +25126,9 @@ var __webpack_modules__ = { ]; const WS_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; const WS_MAX_HEADER_BYTES = 16 * 1024; - const WS_MAX_MESSAGE_BYTES = 4 * 1024 * 1024; - const WS_MAX_BUFFER_BYTES = 8 * 1024 * 1024; + const WS_MAX_MESSAGE_BYTES = 16 * 1024 * 1024; + const WS_MAX_BUFFER_BYTES = 32 * 1024 * 1024; + const CODEX_SEND_MAX_BYTES = 4 * 1024 * 1024; const WS_MAX_WRITE_BYTES = 8 * 1024 * 1024; const CODEX_MAX_REQUESTS = 128; const CODEX_MAX_LISTENERS = 128; @@ -26048,7 +26319,7 @@ var __webpack_modules__ = { ].includes(whenBusy)) throw new RangeError("--when-busy must be reject, queue, or persistent steer"); if (whenBusy === "steer" && (typeof expectedTurnId !== "string" || !ID_PATTERN.test(expectedTurnId))) throw new RangeError("steer requires expectedTurnId"); threadId = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); - if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > WS_MAX_MESSAGE_BYTES) throw new RangeError("Message must contain text within 4 MiB"); + if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > CODEX_SEND_MAX_BYTES) throw new RangeError("Message must contain text within 4 MiB"); if (!envelope || typeof envelope.messageId !== "string" || !ID_PATTERN.test(envelope.messageId)) throw new RangeError("Invalid envelope messageId"); const validated = buildEnvelope({ correlationId: envelope.correlationId, @@ -26839,6 +27110,13 @@ var __webpack_modules__ = { return null; } } + function codexStateEntries(data) { + const nested = data?.['electron-persisted-atom-state']; + return [ + nested, + data + ].filter((value)=>value && typeof value === 'object' && !Array.isArray(value)); + } function findRemoteThreadHost(threadId, env = process.env) { let bare; try { @@ -26850,7 +27128,7 @@ var __webpack_modules__ = { const data = loadCodexGlobalState(env); if (!data) return null; const hostNames = collectHostNames(data); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; @@ -26883,20 +27161,20 @@ var __webpack_modules__ = { } function collectHostNames(data) { const names = new Map(); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)){ if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; if (!value || typeof value !== 'object') continue; if (Array.isArray(value)) { for (const entry of value){ const pair = hostNameFromEntry(entry); - if (pair) names.set(pair.hostId, pair.hostName); + if (pair && !names.has(pair.hostId)) names.set(pair.hostId, pair.hostName); } continue; } for (const [hostId, entry] of Object.entries(value)){ const fromEntry = hostNameFromEntry(entry); if (fromEntry) { - names.set(fromEntry.hostId, fromEntry.hostName); + if (!names.has(fromEntry.hostId)) names.set(fromEntry.hostId, fromEntry.hostName); continue; } const label = stringField(entry, [ @@ -26907,7 +27185,7 @@ var __webpack_modules__ = { 'label', 'title' ]); - if (label) names.set(hostId, label); + if (label && !names.has(hostId)) names.set(hostId, label); } } return names; @@ -27023,7 +27301,8 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { IT: ()=>loadCodexGlobalState, R3: ()=>mapRemoteThreadError, - Rg: ()=>RemoteThreadNotLoadedError1 + Rg: ()=>RemoteThreadNotLoadedError1, + xr: ()=>codexStateEntries }); }, "./src/core/codex/thread-id.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index c01e584..e2a2c53 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -7083,7 +7083,7 @@ var __webpack_modules__ = { type: 'boolean' }, limit: { - default: 100, + description: 'Recent default 100; full default 2000', type: 'number' }, openTimeoutMs: { @@ -7108,7 +7108,7 @@ var __webpack_modules__ = { }; const inputSchema = zod__rspack_import_2.Ikc({ full: zod__rspack_import_2.zMY().default(false), - limit: zod__rspack_import_2.aig().int().min(1).max(2000).default(100), + limit: zod__rspack_import_2.aig().int().min(1).max(2000).optional(), openTimeoutMs: zod__rspack_import_2.aig().int().min(1).max(600000).default(90000), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), threadId: zod__rspack_import_2.YjP().min(1).max(256) @@ -7354,6 +7354,10 @@ var __webpack_modules__ = { description: 'Max threads (1-200)', type: 'number' }, + cursor: { + description: 'Opaque nextCursor from a previous page', + type: 'string' + }, modelProvider: { description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' @@ -7370,6 +7374,7 @@ var __webpack_modules__ = { groupBy: zod__rspack_import_2.euz('host').optional(), host: zod__rspack_import_2.YjP().min(1).max(256).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), + cursor: zod__rspack_import_2.YjP().min(1).max(4096).optional(), modelProvider: zod__rspack_import_2.YjP().min(1).max(256).optional(), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() }).strict(); @@ -7381,7 +7386,7 @@ var __webpack_modules__ = { const where = row.location === 'remote' ? ` [remote ${row.hostName || row.hostId || '?'}]` : ' [local]'; const provider = row.modelProvider ? ` {${row.modelProvider}}` : ''; return `${row.selected ? '* ' : ' '}${row.threadId ?? ''} ${row.title ?? ''}` + (row.pinned ? ' (pinned)' : '') + where + provider; - }).join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); + }).join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` + (out.nextCursor ? `\nnextCursor: ${out.nextCursor}` : '') : (0, _core_chatgpt_desktop_routes_js__rspack_import_1.D6)(out); return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { value: out, children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { @@ -9706,9 +9711,10 @@ var __webpack_modules__ = { } const matched = []; let cursor; - for(let page = 0; page < 20 && matched.length < limit; page++){ + let exhausted = false; + for(let page = 0; page < 400 && matched.length < limit; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit: 200, + limit: 25, cursor, modelProviders }); @@ -9717,7 +9723,10 @@ var __webpack_modules__ = { if (threadMatchesQuery(mapped, needle)) matched.push(mapped); if (matched.length >= limit) break; } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + if (out.nextCursor == null || typeof out.nextCursor !== 'string') { + exhausted = true; + break; + } cursor = out.nextCursor; } return { @@ -9726,34 +9735,48 @@ var __webpack_modules__ = { query, nextCursor: null, threads: matched.slice(0, limit), - modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, + ...!exhausted && matched.length < limit ? { + warnings: [ + 'Search stopped after 400 app-server pages; results may be incomplete' + ] + } : {} }; } async function discoverModelProviders() { const providers = new Set(); + let threadCount = 0; let cursor; - for(let page = 0; page < 20; page++){ + let complete = false; + for(let page = 0; page < 400; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit: 200, + limit: 25, cursor, modelProviders: [] }); + threadCount += out.threads.length; for (const thread of out.threads){ if (typeof thread.modelProvider === 'string' && thread.modelProvider) { providers.add(thread.modelProvider); } } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + if (out.nextCursor == null || typeof out.nextCursor !== 'string') { + complete = true; + break; + } cursor = out.nextCursor; } return { providers: [ ...providers ].sort(), - source: 'thread/list-distinct' + source: 'thread/list-distinct', + threadCount, + complete }; } - async function appServerReadThread({ threadId, limit = 100, full = false }) { + async function appServerReadThread({ threadId, limit, full = false }) { + limit ??= full ? 2000 : 100; const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); if (remote) { @@ -9782,7 +9805,7 @@ var __webpack_modules__ = { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { const meta = await readThreadMetadata(client, bare); - const turns = await listTurnsFull(client, bare, { + const { turns, complete } = await listTurnsFull(client, bare, { limit, full }); @@ -9792,6 +9815,7 @@ var __webpack_modules__ = { backend: 'app-server', limit, full, + complete, title: meta.title, cwd: meta.cwd, status: meta.status, @@ -9880,12 +9904,13 @@ var __webpack_modules__ = { let itemsView = true; let method = 'thread/turns/list'; const seen = new Set(); + let complete = false; while(collected.length < limit){ let result; try { result = await client.request(method, { threadId, - limit: Math.min(100, limit - collected.length), + limit: Math.min(10, limit - collected.length), sortDirection: full ? 'asc' : 'desc', ...method === 'thread/turns/list' && itemsView ? { itemsView: 'full' @@ -9908,7 +9933,10 @@ var __webpack_modules__ = { } if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); collected.push(...result.data); - if (result.nextCursor == null) break; + if (result.nextCursor == null) { + complete = true; + break; + } if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { throw new Error(`${method} returned an invalid or repeated cursor`); } @@ -9916,7 +9944,10 @@ var __webpack_modules__ = { cursor = result.nextCursor; } const turns = normalizeTurns(collected.slice(0, limit)); - return full ? turns : turns.reverse(); + return { + turns: full ? turns : turns.reverse(), + complete + }; } function normalizeTurns(raw) { const turns = []; @@ -9972,7 +10003,7 @@ var __webpack_modules__ = { assistantText } : {}, startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, - endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + endedAt: typeof row.completedAt === 'number' ? row.completedAt : typeof row.endedAt === 'number' ? row.endedAt : null }; } function normalizeLeafItem(id, row) { @@ -9988,12 +10019,13 @@ var __webpack_modules__ = { role, text, startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, - endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + endedAt: typeof row.completedAt === 'number' ? row.completedAt : typeof row.endedAt === 'number' ? row.endedAt : null }; } function extractText(row) { if (typeof row.text === 'string') return row.text; if (typeof row.content === 'string') return row.content; + if (Array.isArray(row.content)) return row.content.filter((part)=>Boolean(part) && typeof part === 'object' && !Array.isArray(part)).map((part)=>typeof part.text === 'string' ? part.text : '').filter(Boolean).join('\n'); if (typeof row.preview === 'string') return row.preview; return ''; } @@ -10100,7 +10132,8 @@ var __webpack_modules__ = { turns, backend: 'cdp', limit, - full + full, + complete: false }; } async sendMessage({ threadId, text, project, openTimeoutMs = 90000 }) { @@ -10414,6 +10447,7 @@ var __webpack_modules__ = { const project = projectFor(row); out.push({ threadId, + hostId: row.getAttribute('data-app-action-sidebar-thread-host-id') || null, title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', @@ -10442,6 +10476,26 @@ var __webpack_modules__ = { if (!row) return { ok: false, error: 'thread-not-found' }; row.click(); return { ok: true, threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || candidates[0] }; + })()`; + } + function navigateToThreadExpression(threadId) { + const bare = durableThreadKey(threadId); + return `(async () => { + const root = window.__codexRoot?._internalRoot?.current; + const queue = [root]; + let scanned = 0; + while (queue.length && scanned++ < 10000) { + const fiber = queue.shift(); + if (!fiber) continue; + const router = fiber.memoizedProps?.router; + if (router?.navigate && router?.state?.location) { + await router.navigate(${JSON.stringify(`/local/${bare}`)}); + return { ok: true, via: 'router' }; + } + if (fiber.child) queue.push(fiber.child); + if (fiber.sibling) queue.push(fiber.sibling); + } + return { ok: false, error: 'router-not-found' }; })()`; } function startNewChatExpression(project) { @@ -10451,8 +10505,11 @@ var __webpack_modules__ = { if (projectSel) { const preferred = document.querySelector(projectSel); if (preferred) { - preferred.click(); - return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; + const row = preferred.closest('.group') || preferred.parentElement; + row?.scrollIntoView({ block: 'center' }); + const rowBox = row?.getBoundingClientRect(); + return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)}, + hoverX: rowBox?.left + rowBox?.width / 2, hoverY: rowBox?.top + rowBox?.height / 2 }; } return { ok: false, error: 'project-not-found' }; } @@ -10461,6 +10518,15 @@ var __webpack_modules__ = { if (!fallback) return { ok: false, error: 'new-chat-not-found' }; fallback.click(); return { ok: true, via: 'fallback' }; + })()`; + } + function projectButtonBoxExpression(project) { + return `(() => { + const button = document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); + if (!button) return null; + const box = button.getBoundingClientRect(); + return { x: box.left + box.width / 2, y: box.top + box.height / 2, + visible: box.width > 0 && box.height > 0 && getComputedStyle(button.parentElement).opacity !== '0' }; })()`; } const LOADING_TASK_GONE_EXPRESSION = `(() => { @@ -10474,6 +10540,9 @@ var __webpack_modules__ = { const text = (surface.innerText || '').replace(/\\u2026/g, '…'); return !text.includes(${JSON.stringify(LOADING_TASK_TEXT)}); })()`; + const ARCHIVED_THREAD_EXPRESSION = `(() => Array.from(document.querySelectorAll('main')) + .some((main) => (main.innerText || '').includes('This task is archived') + && (main.innerText || '').includes('Unarchive this task to open it')))()`; const FOCUS_COMPOSER_EXPRESSION = `(() => { const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); if (!composer) return { ok: false, error: 'composer-not-found' }; @@ -10578,27 +10647,60 @@ var __webpack_modules__ = { pinned: Boolean(row.pinned), selected: Boolean(row.selected), kind: String(row.kind ?? 'unknown'), + ...row.hostId ? { + hostId: row.hostId, + location: row.hostId === 'local' ? 'local' : 'remote' + } : {}, ...row.project ? { project: String(row.project) } : {} })); } async function openThreadInDom(session, sessionId, threadId) { + const current = await readConversationIdFromDom(session, sessionId); + if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; + if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + const rows = await listThreadsFromDom(session, sessionId, { + limit: 200 + }); + if (rows.some((row)=>row.selected && row.threadId === threadId)) return; + } const result = await session.evaluate(openThreadExpression(threadId), { sessionId }); if (!result?.ok) { + if (result?.error === 'thread-not-found' && !(0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + const navigated = await session.evaluate(navigateToThreadExpression(threadId), { + sessionId + }); + if (navigated?.ok) return; + } throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); } } async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS, threadId } = {}) { const deadline = Date.now() + timeoutMs; + let loadingGone = false; + let lastConversationId = ''; + let archivedSince = null; while(Date.now() < deadline){ + if (threadId && threadId !== 'new' && await session.evaluate(ARCHIVED_THREAD_EXPRESSION, { + sessionId + }) === true) { + archivedSince ??= Date.now(); + if (Date.now() - archivedSince >= 500) { + throw new Error(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived; unarchive it in Desktop before opening`); + } + } else { + archivedSince = null; + } const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { sessionId }); + loadingGone ||= gone; if (gone) { const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; + lastConversationId = current; if (!threadId) return; if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { @@ -10610,7 +10712,7 @@ var __webpack_modules__ = { } await delay(250); } - throw new Error(`ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); + throw new Error(loadingGone ? `ChatGPT Desktop timed out waiting for conversation ${JSON.stringify(threadId)}; displayed conversation ${JSON.stringify(lastConversationId)} after ${timeoutMs}ms` : `ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); } async function startNewChatInDom(session, sessionId, { project } = {}) { const result = await session.evaluate(startNewChatExpression(project), { @@ -10619,6 +10721,52 @@ var __webpack_modules__ = { if (!result?.ok) { throw new Error(project ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` : 'ChatGPT Desktop "New chat" button not found'); } + if (result.via === 'project') { + if (![ + result.hoverX, + result.hoverY + ].every(Number.isFinite)) { + throw new Error(`ChatGPT Desktop project button has no visible box for ${JSON.stringify(project)}`); + } + await session.send('Input.dispatchMouseEvent', { + type: 'mouseMoved', + x: result.hoverX, + y: result.hoverY + }, { + sessionId + }); + const button = await session.evaluate(projectButtonBoxExpression(project), { + sessionId + }); + if (!button?.visible || !Number.isFinite(button.x) || !Number.isFinite(button.y)) { + throw new Error(`ChatGPT Desktop project button did not appear after hover for ${JSON.stringify(project)}`); + } + await session.send('Input.dispatchMouseEvent', { + type: 'mouseMoved', + x: button.x, + y: button.y + }, { + sessionId + }); + await session.send('Input.dispatchMouseEvent', { + type: 'mousePressed', + x: button.x, + y: button.y, + button: 'left', + clickCount: 1 + }, { + sessionId + }); + await session.send('Input.dispatchMouseEvent', { + type: 'mouseReleased', + x: button.x, + y: button.y, + button: 'left', + clickCount: 1 + }, { + sessionId + }); + } return { via: result.via ?? 'unknown' }; @@ -10765,16 +10913,18 @@ var __webpack_modules__ = { } async function readTurnsFromDom(session, sessionId, { limit = 100, full = false, threadId, idleWheels = DEFAULT_FULL_READ_IDLE_WHEELS, maxWheels = DEFAULT_FULL_READ_MAX_WHEELS } = {}) { const collected = new Map(); + const order1 = []; const ingest = async ()=>{ + const older = []; for (const turn of (await harvestVisibleTurns(session, sessionId))){ + if (!collected.has(turn.turnKey)) older.push(turn.turnKey); collected.set(turn.turnKey, turn); } + order1.unshift(...older); }; await ingest(); if (!full) { - const visible = [ - ...collected.values() - ]; + const visible = order1.map((key)=>collected.get(key)); return limit > 0 ? visible.slice(-limit) : visible; } let idle = 0; @@ -10803,9 +10953,7 @@ var __webpack_modules__ = { } if (threadId && collected.has(threadId)) break; } - const all = [ - ...collected.values() - ]; + const all = order1.map((key)=>collected.get(key)); return limit > 0 ? all.slice(0, limit) : all; } function delay(ms) { @@ -11075,6 +11223,8 @@ var __webpack_modules__ = { listHosts: _remote_threads_js__rspack_import_4.Kl, discoverModelProviders: _app_server_fallback_js__rspack_import_1.X }; + const REMOTE_PAGE_CURSOR = 'desktop-remote-page:'; + const APP_START_CURSOR = 'desktop-app-start'; class ChatGptDesktopFacade { #cdp; #port; @@ -11105,23 +11255,21 @@ var __webpack_modules__ = { const limit = options.limit ?? 50; const host = normalizeHostFilter(options.host); const modelProviders = modelProvidersFromFilter(options.modelProvider); - let appList = null; - let appError; - try { - appList = await this.#fallbacks.listThreads({ - limit, - modelProviders - }); - } catch (error) { - appError = error; + const remoteOffset = options.cursor?.startsWith(REMOTE_PAGE_CURSOR) ? Number(options.cursor.slice(REMOTE_PAGE_CURSOR.length)) : null; + if (remoteOffset !== null && (!Number.isSafeInteger(remoteOffset) || remoteOffset < 1)) { + throw new Error('Invalid ChatGPT Desktop remote page cursor'); } + const inventoryPage = !options.cursor || remoteOffset !== null; + const remotes = inventoryPage ? this.#listRemotes() : []; let cdpList = null; let cdpError; try { - await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads({ - limit - }); + if (inventoryPage) { + await this.#ensureCdp(); + cdpList = await this.#cdp.listThreads({ + limit: 200 + }); + } } catch (error) { if (isCdpFailure(error)) { this.#cdpConnected = false; @@ -11129,33 +11277,87 @@ var __webpack_modules__ = { cdpError = error; } } - const remotes = this.#listRemotes(); + if (inventoryPage && host !== 'local') { + const remoteInventory = finalizeThreadList({ + backend: cdpList?.backend ?? 'remote-state', + limit: 10000, + threads: cdpList?.threads.filter((thread)=>thread.location === 'remote') ?? [] + }, { + limit: 10000, + host, + modelProvider: options.modelProvider, + remotes + }); + const offset = remoteOffset ?? 0; + if (remoteOffset !== null || remoteInventory.threads.length >= limit) { + const page = remoteInventory.threads.slice(offset, offset + limit); + const nextOffset = offset + page.length; + const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; + return { + ...remoteInventory, + threads: page, + limit, + nextCursor, + ...options.groupBy === 'host' ? { + groupBy: 'host', + groups: groupThreadsByHost(page) + } : {} + }; + } + } + const remoteKeys = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; + const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); + let appList = null; + let appError; + try { + appList = await this.#fallbacks.listThreads({ + limit: appLimit, + cursor: options.cursor === APP_START_CURSOR ? undefined : options.cursor, + modelProviders + }); + } catch (error) { + appError = error; + } let base = null; if (appList && cdpList) base = mergeThreadLists(appList, cdpList); else if (appList) base = appList; else if (cdpList) base = cdpList; else if (remotes.length) base = { - backend: 'app-server', + backend: 'remote-state', limit, threads: [] }; else if (cdpError) throw cdpError; else if (appError) throw appError; else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); - return finalizeThreadList(base, { + const result = finalizeThreadList(base, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes }); + const withCursor = host === 'all' || host === 'local' ? result : { + ...result, + nextCursor: null + }; + return appError ? { + ...withCursor, + warnings: [ + `App-server list failed: ${appError instanceof Error ? appError.message : String(appError)}` + ] + } : withCursor; } async listHosts() { const remotes = this.#listRemotes(); + const cdpRows = typeof this.#cdp.listThreads === 'function' ? (await this.#tryCdpList({ + limit: 200 + }))?.threads ?? [] : []; let localThreadCount = 0; try { const local = await this.#fallbacks.listThreads({ - limit: 200, + limit: 25, modelProviders: [] }); localThreadCount = local.threads.length; @@ -11188,11 +11390,28 @@ var __webpack_modules__ = { }); } } - const hostsSource = 'remote-thread-summaries-v3+local'; + for (const thread of cdpRows){ + if (thread.location !== 'remote' || !thread.hostId) continue; + if (!byId.has(thread.hostId)) byId.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName ?? null, + location: 'remote', + threadCount: 0 + }); + } + const hostsSource = 'local+remote-thread-summaries-v3+managed-connections' + (cdpRows.length ? '+cdp' : ''); const remoteCounts = new Map(); for (const thread of remotes){ remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); } + const remoteIds = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + for (const thread of cdpRows){ + if (thread.location !== 'remote' || !thread.hostId) continue; + const id = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; + if (remoteIds.has(id)) continue; + remoteIds.add(id); + remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + } const withCounts = [ ...byId.values() ].map((host)=>host.hostId === 'local' ? { @@ -11208,6 +11427,7 @@ var __webpack_modules__ = { }); let modelProviders = []; let modelProvidersSource = 'thread/list-distinct'; + const warnings = []; try { const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_1.X; const discovered = await discover(); @@ -11215,7 +11435,10 @@ var __webpack_modules__ = { ...discovered.providers ]; modelProvidersSource = discovered.source; - } catch { + if (typeof discovered.threadCount === 'number') localThreadCount = discovered.threadCount; + if (discovered.complete === false) warnings.push('Provider discovery stopped before the final app-server page'); + } catch (error) { + warnings.push(`Model provider discovery failed: ${error instanceof Error ? error.message : String(error)}`); modelProviders = [ ...new Set(remotes.map((thread)=>thread.modelProvider).filter((value)=>typeof value === 'string' && Boolean(value))) ].sort(); @@ -11228,11 +11451,17 @@ var __webpack_modules__ = { ]) ].sort(); return { - hosts: withCounts, + hosts: withCounts.map((host)=>host.hostId === 'local' ? { + ...host, + threadCount: localThreadCount + } : host), hostsSource, modelProviders, modelProvidersSource, - backend: 'app-server' + backend: cdpRows.length ? remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp' : remotes.length ? 'app-server+remote-state' : 'app-server', + ...warnings.length ? { + warnings + } : {} }; } async searchThreads(options) { @@ -11261,13 +11490,14 @@ var __webpack_modules__ = { query: options.query, threads: withRemotes.threads.filter((thread)=>threadMatchesQuery(thread, needle)) }; - return finalizeThreadList(filtered, { + const result = finalizeThreadList(filtered, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: [] }); + return result; } catch (appError) { const cdpList = await this.#tryCdpList({ limit @@ -11283,17 +11513,23 @@ var __webpack_modules__ = { query: options.query, threads: (cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) }; - return finalizeThreadList(filtered, { + const result = finalizeThreadList(filtered, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) }); + return { + ...result, + warnings: [ + `App-server search failed: ${appError instanceof Error ? appError.message : String(appError)}` + ] + }; } } async readThread(options) { - const limit = options.limit ?? 100; + const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { await this.#ensureCdp(); @@ -11313,11 +11549,18 @@ var __webpack_modules__ = { if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; - return this.#cdp.readThread({ + const fallback = await this.#cdp.readThread({ ...options, limit, full }); + return { + ...fallback, + complete: false, + warnings: [ + `App-server read failed: ${appError instanceof Error ? appError.message : String(appError)}` + ] + }; } } async sendMessage(options) { @@ -11342,13 +11585,13 @@ var __webpack_modules__ = { reachable: false }; } - const reachable = cdpStatus.reachable || Boolean(appServerFallback?.reachable); + const reachable = cdpStatus.reachable; return { ...cdpStatus, port: this.#port, appServerFallback, reachable, - message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/search/read' : cdpStatus.message, + message: cdpStatus.reachable ? cdpStatus.message : cdpStatus.message, exitCode: reachable ? 0 : 1 }; } @@ -11416,7 +11659,10 @@ var __webpack_modules__ = { pinned: withLocal.pinned || cdp.pinned, selected: cdp.selected, kind: cdp.kind || withLocal.kind, - project: cdp.project ?? withLocal.project + project: cdp.project ?? withLocal.project, + location: cdp.location === 'remote' ? 'remote' : withLocal.location, + hostId: cdp.location === 'remote' ? cdp.hostId ?? null : withLocal.hostId, + hostName: cdp.location === 'remote' ? cdp.hostName ?? null : withLocal.hostName }; }); for (const thread of cdpList.threads){ @@ -11424,7 +11670,7 @@ var __webpack_modules__ = { merged.push(thread); } return { - backend: appList.backend, + backend: 'app-server+cdp', limit: appList.limit, nextCursor: appList.nextCursor, ...appList.query !== undefined ? { @@ -11440,7 +11686,7 @@ var __webpack_modules__ = { ])); const locals = base.threads.map((thread)=>{ const remote = remoteById.get((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId); - if (remote && thread.location === undefined) { + if (remote) { return { ...thread, ...remote, @@ -11470,6 +11716,7 @@ var __webpack_modules__ = { hostName: remote.hostName ?? null }); } + if (remotes.length) merged.sort((a, b)=>Number(b.location === 'remote') - Number(a.location === 'remote')); const filtered = merged.filter((thread)=>{ if (!hostMatches(thread, host)) return false; if (!modelProviderMatches(thread, modelProvider)) return false; @@ -11477,7 +11724,7 @@ var __webpack_modules__ = { }); const limited = filtered.slice(0, limit); const result = { - backend: base.backend, + backend: remotes.length ? base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' : base.backend === 'app-server' ? 'app-server+remote-state' : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend : base.backend, limit, threads: limited, ...base.nextCursor !== undefined ? { @@ -11650,7 +11897,7 @@ var __webpack_modules__ = { const hostNames = collectHostNames(data); const out = []; const seen = new Set(); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of (0, _codex_remote_control_js__rspack_import_0.xr)(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; @@ -11702,12 +11949,12 @@ var __webpack_modules__ = { const data = (0, _codex_remote_control_js__rspack_import_0.IT)(env); if (data) { const hostNames = collectHostNames(data); - for (const key of Object.keys(data)){ + for (const [key, summary] of (0, _codex_remote_control_js__rspack_import_0.xr)(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; - const summary = data[key]; const hostName = hostNames.get(hostId) ?? extractHostName(summary) ?? null; + if (byHost.has(hostId)) continue; byHost.set(hostId, { hostId, hostName, @@ -11715,6 +11962,22 @@ var __webpack_modules__ = { threadCount: 0 }); } + const connections = data['codex-managed-remote-connections']; + if (Array.isArray(connections)) for (const entry of connections){ + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) continue; + const hostId = stringField(entry, [ + 'hostId' + ]); + if (hostId && !byHost.has(hostId)) byHost.set(hostId, { + hostId, + hostName: stringField(entry, [ + 'displayName', + 'alias' + ]), + location: 'remote', + threadCount: 0 + }); + } } for (const thread of remotes){ const existing = byHost.get(thread.hostId); @@ -11743,20 +12006,25 @@ var __webpack_modules__ = { } function collectHostNames(data) { const names = new Map(); - for (const [key, value] of Object.entries(data)){ + const connections = data['codex-managed-remote-connections']; + if (Array.isArray(connections)) for (const entry of connections){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + for (const [key, value] of (0, _codex_remote_control_js__rspack_import_0.xr)(data).flatMap(Object.entries)){ if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; if (!value || typeof value !== 'object') continue; if (Array.isArray(value)) { for (const entry of value){ const pair = hostNameFromEntry(entry); - if (pair) names.set(pair.hostId, pair.hostName); + if (pair && !names.has(pair.hostId)) names.set(pair.hostId, pair.hostName); } continue; } for (const [hostId, entry] of Object.entries(value)){ const fromEntry = hostNameFromEntry(entry); if (fromEntry) { - names.set(fromEntry.hostId, fromEntry.hostName); + if (!names.has(fromEntry.hostId)) names.set(fromEntry.hostId, fromEntry.hostName); continue; } const label = stringField(entry, [ @@ -11767,7 +12035,7 @@ var __webpack_modules__ = { 'label', 'title' ]); - if (label) names.set(hostId, label); + if (label && !names.has(hostId)) names.set(hostId, label); } } return names; @@ -12046,6 +12314,7 @@ var __webpack_modules__ = { const listThreadsSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() @@ -12064,7 +12333,7 @@ var __webpack_modules__ = { const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, - limit: zod__rspack_import_4.aig().int().min(1).max(2000).default(100), + limit: zod__rspack_import_4.aig().int().min(1).max(2000).optional(), full: zod__rspack_import_4.zMY().default(false), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); @@ -12156,6 +12425,7 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ limit: input.limit, + cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, groupBy: input.groupBy @@ -12210,7 +12480,7 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ threadId: input.threadId, - limit: input.limit, + limit: input.limit ?? (input.full ? 2000 : 100), full: input.full, openTimeoutMs: input.openTimeoutMs })); @@ -40627,7 +40897,7 @@ var __webpack_modules__ = { "required": false }, { - "defaultValue": 100, + "description": "Recent default 100; full default 2000", "key": "limit", "kind": "number", "option": "limit", @@ -40811,6 +41081,14 @@ var __webpack_modules__ = { "description": "List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.", "exitCode": "result", "options": [ + { + "description": "Opaque nextCursor from a previous page", + "key": "cursor", + "kind": "string", + "option": "cursor", + "repeated": false, + "required": false + }, { "choices": [ "host" @@ -43071,8 +43349,9 @@ var __webpack_modules__ = { ]; const WS_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; const WS_MAX_HEADER_BYTES = 16 * 1024; - const WS_MAX_MESSAGE_BYTES = 4 * 1024 * 1024; - const WS_MAX_BUFFER_BYTES = 8 * 1024 * 1024; + const WS_MAX_MESSAGE_BYTES = 16 * 1024 * 1024; + const WS_MAX_BUFFER_BYTES = 32 * 1024 * 1024; + const CODEX_SEND_MAX_BYTES = 4 * 1024 * 1024; const WS_MAX_WRITE_BYTES = 8 * 1024 * 1024; const CODEX_MAX_REQUESTS = 128; const CODEX_MAX_LISTENERS = 128; @@ -44263,7 +44542,7 @@ var __webpack_modules__ = { ].includes(whenBusy)) throw new RangeError("--when-busy must be reject, queue, or persistent steer"); if (whenBusy === "steer" && (typeof expectedTurnId !== "string" || !ID_PATTERN.test(expectedTurnId))) throw new RangeError("steer requires expectedTurnId"); threadId = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); - if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > WS_MAX_MESSAGE_BYTES) throw new RangeError("Message must contain text within 4 MiB"); + if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > CODEX_SEND_MAX_BYTES) throw new RangeError("Message must contain text within 4 MiB"); if (!envelope || typeof envelope.messageId !== "string" || !ID_PATTERN.test(envelope.messageId)) throw new RangeError("Invalid envelope messageId"); const validated = buildEnvelope({ correlationId: envelope.correlationId, @@ -45054,6 +45333,13 @@ var __webpack_modules__ = { return null; } } + function codexStateEntries(data) { + const nested = data?.['electron-persisted-atom-state']; + return [ + nested, + data + ].filter((value)=>value && typeof value === 'object' && !Array.isArray(value)); + } function findRemoteThreadHost(threadId, env = process.env) { let bare; try { @@ -45065,7 +45351,7 @@ var __webpack_modules__ = { const data = loadCodexGlobalState(env); if (!data) return null; const hostNames = collectHostNames(data); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; @@ -45098,20 +45384,20 @@ var __webpack_modules__ = { } function collectHostNames(data) { const names = new Map(); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)){ if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; if (!value || typeof value !== 'object') continue; if (Array.isArray(value)) { for (const entry of value){ const pair = hostNameFromEntry(entry); - if (pair) names.set(pair.hostId, pair.hostName); + if (pair && !names.has(pair.hostId)) names.set(pair.hostId, pair.hostName); } continue; } for (const [hostId, entry] of Object.entries(value)){ const fromEntry = hostNameFromEntry(entry); if (fromEntry) { - names.set(fromEntry.hostId, fromEntry.hostName); + if (!names.has(fromEntry.hostId)) names.set(fromEntry.hostId, fromEntry.hostName); continue; } const label = stringField(entry, [ @@ -45122,7 +45408,7 @@ var __webpack_modules__ = { 'label', 'title' ]); - if (label) names.set(hostId, label); + if (label && !names.has(hostId)) names.set(hostId, label); } } return names; @@ -45238,7 +45524,8 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { IT: ()=>loadCodexGlobalState, R3: ()=>mapRemoteThreadError, - Rg: ()=>RemoteThreadNotLoadedError1 + Rg: ()=>RemoteThreadNotLoadedError1, + xr: ()=>codexStateEntries }); }, "./src/core/codex/thread-id.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index 7a1cb80..acf0247 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8113,9 +8113,10 @@ var __webpack_modules__ = { } const matched = []; let cursor; - for(let page = 0; page < 20 && matched.length < limit; page++){ + let exhausted = false; + for(let page = 0; page < 400 && matched.length < limit; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit: 200, + limit: 25, cursor, modelProviders }); @@ -8124,7 +8125,10 @@ var __webpack_modules__ = { if (threadMatchesQuery(mapped, needle)) matched.push(mapped); if (matched.length >= limit) break; } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + if (out.nextCursor == null || typeof out.nextCursor !== 'string') { + exhausted = true; + break; + } cursor = out.nextCursor; } return { @@ -8133,34 +8137,48 @@ var __webpack_modules__ = { query, nextCursor: null, threads: matched.slice(0, limit), - modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, + ...!exhausted && matched.length < limit ? { + warnings: [ + 'Search stopped after 400 app-server pages; results may be incomplete' + ] + } : {} }; } async function discoverModelProviders() { const providers = new Set(); + let threadCount = 0; let cursor; - for(let page = 0; page < 20; page++){ + let complete = false; + for(let page = 0; page < 400; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit: 200, + limit: 25, cursor, modelProviders: [] }); + threadCount += out.threads.length; for (const thread of out.threads){ if (typeof thread.modelProvider === 'string' && thread.modelProvider) { providers.add(thread.modelProvider); } } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + if (out.nextCursor == null || typeof out.nextCursor !== 'string') { + complete = true; + break; + } cursor = out.nextCursor; } return { providers: [ ...providers ].sort(), - source: 'thread/list-distinct' + source: 'thread/list-distinct', + threadCount, + complete }; } - async function appServerReadThread({ threadId, limit = 100, full = false }) { + async function appServerReadThread({ threadId, limit, full = false }) { + limit ??= full ? 2000 : 100; const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); if (remote) { @@ -8189,7 +8207,7 @@ var __webpack_modules__ = { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { const meta = await readThreadMetadata(client, bare); - const turns = await listTurnsFull(client, bare, { + const { turns, complete } = await listTurnsFull(client, bare, { limit, full }); @@ -8199,6 +8217,7 @@ var __webpack_modules__ = { backend: 'app-server', limit, full, + complete, title: meta.title, cwd: meta.cwd, status: meta.status, @@ -8287,12 +8306,13 @@ var __webpack_modules__ = { let itemsView = true; let method = 'thread/turns/list'; const seen = new Set(); + let complete = false; while(collected.length < limit){ let result; try { result = await client.request(method, { threadId, - limit: Math.min(100, limit - collected.length), + limit: Math.min(10, limit - collected.length), sortDirection: full ? 'asc' : 'desc', ...method === 'thread/turns/list' && itemsView ? { itemsView: 'full' @@ -8315,7 +8335,10 @@ var __webpack_modules__ = { } if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); collected.push(...result.data); - if (result.nextCursor == null) break; + if (result.nextCursor == null) { + complete = true; + break; + } if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { throw new Error(`${method} returned an invalid or repeated cursor`); } @@ -8323,7 +8346,10 @@ var __webpack_modules__ = { cursor = result.nextCursor; } const turns = normalizeTurns(collected.slice(0, limit)); - return full ? turns : turns.reverse(); + return { + turns: full ? turns : turns.reverse(), + complete + }; } function normalizeTurns(raw) { const turns = []; @@ -8379,7 +8405,7 @@ var __webpack_modules__ = { assistantText } : {}, startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, - endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + endedAt: typeof row.completedAt === 'number' ? row.completedAt : typeof row.endedAt === 'number' ? row.endedAt : null }; } function normalizeLeafItem(id, row) { @@ -8395,12 +8421,13 @@ var __webpack_modules__ = { role, text, startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, - endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + endedAt: typeof row.completedAt === 'number' ? row.completedAt : typeof row.endedAt === 'number' ? row.endedAt : null }; } function extractText(row) { if (typeof row.text === 'string') return row.text; if (typeof row.content === 'string') return row.content; + if (Array.isArray(row.content)) return row.content.filter((part)=>Boolean(part) && typeof part === 'object' && !Array.isArray(part)).map((part)=>typeof part.text === 'string' ? part.text : '').filter(Boolean).join('\n'); if (typeof row.preview === 'string') return row.preview; return ''; } @@ -8507,7 +8534,8 @@ var __webpack_modules__ = { turns, backend: 'cdp', limit, - full + full, + complete: false }; } async sendMessage({ threadId, text, project, openTimeoutMs = 90000 }) { @@ -8821,6 +8849,7 @@ var __webpack_modules__ = { const project = projectFor(row); out.push({ threadId, + hostId: row.getAttribute('data-app-action-sidebar-thread-host-id') || null, title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', @@ -8849,6 +8878,26 @@ var __webpack_modules__ = { if (!row) return { ok: false, error: 'thread-not-found' }; row.click(); return { ok: true, threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || candidates[0] }; + })()`; + } + function navigateToThreadExpression(threadId) { + const bare = durableThreadKey(threadId); + return `(async () => { + const root = window.__codexRoot?._internalRoot?.current; + const queue = [root]; + let scanned = 0; + while (queue.length && scanned++ < 10000) { + const fiber = queue.shift(); + if (!fiber) continue; + const router = fiber.memoizedProps?.router; + if (router?.navigate && router?.state?.location) { + await router.navigate(${JSON.stringify(`/local/${bare}`)}); + return { ok: true, via: 'router' }; + } + if (fiber.child) queue.push(fiber.child); + if (fiber.sibling) queue.push(fiber.sibling); + } + return { ok: false, error: 'router-not-found' }; })()`; } function startNewChatExpression(project) { @@ -8858,8 +8907,11 @@ var __webpack_modules__ = { if (projectSel) { const preferred = document.querySelector(projectSel); if (preferred) { - preferred.click(); - return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; + const row = preferred.closest('.group') || preferred.parentElement; + row?.scrollIntoView({ block: 'center' }); + const rowBox = row?.getBoundingClientRect(); + return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)}, + hoverX: rowBox?.left + rowBox?.width / 2, hoverY: rowBox?.top + rowBox?.height / 2 }; } return { ok: false, error: 'project-not-found' }; } @@ -8868,6 +8920,15 @@ var __webpack_modules__ = { if (!fallback) return { ok: false, error: 'new-chat-not-found' }; fallback.click(); return { ok: true, via: 'fallback' }; + })()`; + } + function projectButtonBoxExpression(project) { + return `(() => { + const button = document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); + if (!button) return null; + const box = button.getBoundingClientRect(); + return { x: box.left + box.width / 2, y: box.top + box.height / 2, + visible: box.width > 0 && box.height > 0 && getComputedStyle(button.parentElement).opacity !== '0' }; })()`; } const LOADING_TASK_GONE_EXPRESSION = `(() => { @@ -8881,6 +8942,9 @@ var __webpack_modules__ = { const text = (surface.innerText || '').replace(/\\u2026/g, '…'); return !text.includes(${JSON.stringify(LOADING_TASK_TEXT)}); })()`; + const ARCHIVED_THREAD_EXPRESSION = `(() => Array.from(document.querySelectorAll('main')) + .some((main) => (main.innerText || '').includes('This task is archived') + && (main.innerText || '').includes('Unarchive this task to open it')))()`; const FOCUS_COMPOSER_EXPRESSION = `(() => { const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); if (!composer) return { ok: false, error: 'composer-not-found' }; @@ -8985,27 +9049,60 @@ var __webpack_modules__ = { pinned: Boolean(row.pinned), selected: Boolean(row.selected), kind: String(row.kind ?? 'unknown'), + ...row.hostId ? { + hostId: row.hostId, + location: row.hostId === 'local' ? 'local' : 'remote' + } : {}, ...row.project ? { project: String(row.project) } : {} })); } async function openThreadInDom(session, sessionId, threadId) { + const current = await readConversationIdFromDom(session, sessionId); + if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; + if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + const rows = await listThreadsFromDom(session, sessionId, { + limit: 200 + }); + if (rows.some((row)=>row.selected && row.threadId === threadId)) return; + } const result = await session.evaluate(openThreadExpression(threadId), { sessionId }); if (!result?.ok) { + if (result?.error === 'thread-not-found' && !(0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + const navigated = await session.evaluate(navigateToThreadExpression(threadId), { + sessionId + }); + if (navigated?.ok) return; + } throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); } } async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS, threadId } = {}) { const deadline = Date.now() + timeoutMs; + let loadingGone = false; + let lastConversationId = ''; + let archivedSince = null; while(Date.now() < deadline){ + if (threadId && threadId !== 'new' && await session.evaluate(ARCHIVED_THREAD_EXPRESSION, { + sessionId + }) === true) { + archivedSince ??= Date.now(); + if (Date.now() - archivedSince >= 500) { + throw new Error(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived; unarchive it in Desktop before opening`); + } + } else { + archivedSince = null; + } const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { sessionId }); + loadingGone ||= gone; if (gone) { const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; + lastConversationId = current; if (!threadId) return; if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { @@ -9017,7 +9114,7 @@ var __webpack_modules__ = { } await delay(250); } - throw new Error(`ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); + throw new Error(loadingGone ? `ChatGPT Desktop timed out waiting for conversation ${JSON.stringify(threadId)}; displayed conversation ${JSON.stringify(lastConversationId)} after ${timeoutMs}ms` : `ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); } async function startNewChatInDom(session, sessionId, { project } = {}) { const result = await session.evaluate(startNewChatExpression(project), { @@ -9026,6 +9123,52 @@ var __webpack_modules__ = { if (!result?.ok) { throw new Error(project ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` : 'ChatGPT Desktop "New chat" button not found'); } + if (result.via === 'project') { + if (![ + result.hoverX, + result.hoverY + ].every(Number.isFinite)) { + throw new Error(`ChatGPT Desktop project button has no visible box for ${JSON.stringify(project)}`); + } + await session.send('Input.dispatchMouseEvent', { + type: 'mouseMoved', + x: result.hoverX, + y: result.hoverY + }, { + sessionId + }); + const button = await session.evaluate(projectButtonBoxExpression(project), { + sessionId + }); + if (!button?.visible || !Number.isFinite(button.x) || !Number.isFinite(button.y)) { + throw new Error(`ChatGPT Desktop project button did not appear after hover for ${JSON.stringify(project)}`); + } + await session.send('Input.dispatchMouseEvent', { + type: 'mouseMoved', + x: button.x, + y: button.y + }, { + sessionId + }); + await session.send('Input.dispatchMouseEvent', { + type: 'mousePressed', + x: button.x, + y: button.y, + button: 'left', + clickCount: 1 + }, { + sessionId + }); + await session.send('Input.dispatchMouseEvent', { + type: 'mouseReleased', + x: button.x, + y: button.y, + button: 'left', + clickCount: 1 + }, { + sessionId + }); + } return { via: result.via ?? 'unknown' }; @@ -9172,16 +9315,18 @@ var __webpack_modules__ = { } async function readTurnsFromDom(session, sessionId, { limit = 100, full = false, threadId, idleWheels = DEFAULT_FULL_READ_IDLE_WHEELS, maxWheels = DEFAULT_FULL_READ_MAX_WHEELS } = {}) { const collected = new Map(); + const order = []; const ingest = async ()=>{ + const older = []; for (const turn of (await harvestVisibleTurns(session, sessionId))){ + if (!collected.has(turn.turnKey)) older.push(turn.turnKey); collected.set(turn.turnKey, turn); } + order.unshift(...older); }; await ingest(); if (!full) { - const visible = [ - ...collected.values() - ]; + const visible = order.map((key)=>collected.get(key)); return limit > 0 ? visible.slice(-limit) : visible; } let idle = 0; @@ -9210,9 +9355,7 @@ var __webpack_modules__ = { } if (threadId && collected.has(threadId)) break; } - const all = [ - ...collected.values() - ]; + const all = order.map((key)=>collected.get(key)); return limit > 0 ? all.slice(0, limit) : all; } function delay(ms) { @@ -9482,6 +9625,8 @@ var __webpack_modules__ = { listHosts: _remote_threads_js__rspack_import_4.Kl, discoverModelProviders: _app_server_fallback_js__rspack_import_1.X }; + const REMOTE_PAGE_CURSOR = 'desktop-remote-page:'; + const APP_START_CURSOR = 'desktop-app-start'; class ChatGptDesktopFacade { #cdp; #port; @@ -9512,23 +9657,21 @@ var __webpack_modules__ = { const limit = options.limit ?? 50; const host = normalizeHostFilter(options.host); const modelProviders = modelProvidersFromFilter(options.modelProvider); - let appList = null; - let appError; - try { - appList = await this.#fallbacks.listThreads({ - limit, - modelProviders - }); - } catch (error) { - appError = error; + const remoteOffset = options.cursor?.startsWith(REMOTE_PAGE_CURSOR) ? Number(options.cursor.slice(REMOTE_PAGE_CURSOR.length)) : null; + if (remoteOffset !== null && (!Number.isSafeInteger(remoteOffset) || remoteOffset < 1)) { + throw new Error('Invalid ChatGPT Desktop remote page cursor'); } + const inventoryPage = !options.cursor || remoteOffset !== null; + const remotes = inventoryPage ? this.#listRemotes() : []; let cdpList = null; let cdpError; try { - await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads({ - limit - }); + if (inventoryPage) { + await this.#ensureCdp(); + cdpList = await this.#cdp.listThreads({ + limit: 200 + }); + } } catch (error) { if (isCdpFailure(error)) { this.#cdpConnected = false; @@ -9536,33 +9679,87 @@ var __webpack_modules__ = { cdpError = error; } } - const remotes = this.#listRemotes(); + if (inventoryPage && host !== 'local') { + const remoteInventory = finalizeThreadList({ + backend: cdpList?.backend ?? 'remote-state', + limit: 10000, + threads: cdpList?.threads.filter((thread)=>thread.location === 'remote') ?? [] + }, { + limit: 10000, + host, + modelProvider: options.modelProvider, + remotes + }); + const offset = remoteOffset ?? 0; + if (remoteOffset !== null || remoteInventory.threads.length >= limit) { + const page = remoteInventory.threads.slice(offset, offset + limit); + const nextOffset = offset + page.length; + const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; + return { + ...remoteInventory, + threads: page, + limit, + nextCursor, + ...options.groupBy === 'host' ? { + groupBy: 'host', + groups: groupThreadsByHost(page) + } : {} + }; + } + } + const remoteKeys = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; + const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); + let appList = null; + let appError; + try { + appList = await this.#fallbacks.listThreads({ + limit: appLimit, + cursor: options.cursor === APP_START_CURSOR ? undefined : options.cursor, + modelProviders + }); + } catch (error) { + appError = error; + } let base = null; if (appList && cdpList) base = mergeThreadLists(appList, cdpList); else if (appList) base = appList; else if (cdpList) base = cdpList; else if (remotes.length) base = { - backend: 'app-server', + backend: 'remote-state', limit, threads: [] }; else if (cdpError) throw cdpError; else if (appError) throw appError; else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); - return finalizeThreadList(base, { + const result = finalizeThreadList(base, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes }); + const withCursor = host === 'all' || host === 'local' ? result : { + ...result, + nextCursor: null + }; + return appError ? { + ...withCursor, + warnings: [ + `App-server list failed: ${appError instanceof Error ? appError.message : String(appError)}` + ] + } : withCursor; } async listHosts() { const remotes = this.#listRemotes(); + const cdpRows = typeof this.#cdp.listThreads === 'function' ? (await this.#tryCdpList({ + limit: 200 + }))?.threads ?? [] : []; let localThreadCount = 0; try { const local = await this.#fallbacks.listThreads({ - limit: 200, + limit: 25, modelProviders: [] }); localThreadCount = local.threads.length; @@ -9595,11 +9792,28 @@ var __webpack_modules__ = { }); } } - const hostsSource = 'remote-thread-summaries-v3+local'; + for (const thread of cdpRows){ + if (thread.location !== 'remote' || !thread.hostId) continue; + if (!byId.has(thread.hostId)) byId.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName ?? null, + location: 'remote', + threadCount: 0 + }); + } + const hostsSource = 'local+remote-thread-summaries-v3+managed-connections' + (cdpRows.length ? '+cdp' : ''); const remoteCounts = new Map(); for (const thread of remotes){ remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); } + const remoteIds = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + for (const thread of cdpRows){ + if (thread.location !== 'remote' || !thread.hostId) continue; + const id = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; + if (remoteIds.has(id)) continue; + remoteIds.add(id); + remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + } const withCounts = [ ...byId.values() ].map((host)=>host.hostId === 'local' ? { @@ -9615,6 +9829,7 @@ var __webpack_modules__ = { }); let modelProviders = []; let modelProvidersSource = 'thread/list-distinct'; + const warnings = []; try { const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_1.X; const discovered = await discover(); @@ -9622,7 +9837,10 @@ var __webpack_modules__ = { ...discovered.providers ]; modelProvidersSource = discovered.source; - } catch { + if (typeof discovered.threadCount === 'number') localThreadCount = discovered.threadCount; + if (discovered.complete === false) warnings.push('Provider discovery stopped before the final app-server page'); + } catch (error) { + warnings.push(`Model provider discovery failed: ${error instanceof Error ? error.message : String(error)}`); modelProviders = [ ...new Set(remotes.map((thread)=>thread.modelProvider).filter((value)=>typeof value === 'string' && Boolean(value))) ].sort(); @@ -9635,11 +9853,17 @@ var __webpack_modules__ = { ]) ].sort(); return { - hosts: withCounts, + hosts: withCounts.map((host)=>host.hostId === 'local' ? { + ...host, + threadCount: localThreadCount + } : host), hostsSource, modelProviders, modelProvidersSource, - backend: 'app-server' + backend: cdpRows.length ? remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp' : remotes.length ? 'app-server+remote-state' : 'app-server', + ...warnings.length ? { + warnings + } : {} }; } async searchThreads(options) { @@ -9668,13 +9892,14 @@ var __webpack_modules__ = { query: options.query, threads: withRemotes.threads.filter((thread)=>threadMatchesQuery(thread, needle)) }; - return finalizeThreadList(filtered, { + const result = finalizeThreadList(filtered, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: [] }); + return result; } catch (appError) { const cdpList = await this.#tryCdpList({ limit @@ -9690,17 +9915,23 @@ var __webpack_modules__ = { query: options.query, threads: (cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) }; - return finalizeThreadList(filtered, { + const result = finalizeThreadList(filtered, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) }); + return { + ...result, + warnings: [ + `App-server search failed: ${appError instanceof Error ? appError.message : String(appError)}` + ] + }; } } async readThread(options) { - const limit = options.limit ?? 100; + const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { await this.#ensureCdp(); @@ -9720,11 +9951,18 @@ var __webpack_modules__ = { if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; - return this.#cdp.readThread({ + const fallback = await this.#cdp.readThread({ ...options, limit, full }); + return { + ...fallback, + complete: false, + warnings: [ + `App-server read failed: ${appError instanceof Error ? appError.message : String(appError)}` + ] + }; } } async sendMessage(options) { @@ -9749,13 +9987,13 @@ var __webpack_modules__ = { reachable: false }; } - const reachable = cdpStatus.reachable || Boolean(appServerFallback?.reachable); + const reachable = cdpStatus.reachable; return { ...cdpStatus, port: this.#port, appServerFallback, reachable, - message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/search/read' : cdpStatus.message, + message: cdpStatus.reachable ? cdpStatus.message : cdpStatus.message, exitCode: reachable ? 0 : 1 }; } @@ -9823,7 +10061,10 @@ var __webpack_modules__ = { pinned: withLocal.pinned || cdp.pinned, selected: cdp.selected, kind: cdp.kind || withLocal.kind, - project: cdp.project ?? withLocal.project + project: cdp.project ?? withLocal.project, + location: cdp.location === 'remote' ? 'remote' : withLocal.location, + hostId: cdp.location === 'remote' ? cdp.hostId ?? null : withLocal.hostId, + hostName: cdp.location === 'remote' ? cdp.hostName ?? null : withLocal.hostName }; }); for (const thread of cdpList.threads){ @@ -9831,7 +10072,7 @@ var __webpack_modules__ = { merged.push(thread); } return { - backend: appList.backend, + backend: 'app-server+cdp', limit: appList.limit, nextCursor: appList.nextCursor, ...appList.query !== undefined ? { @@ -9847,7 +10088,7 @@ var __webpack_modules__ = { ])); const locals = base.threads.map((thread)=>{ const remote = remoteById.get((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId); - if (remote && thread.location === undefined) { + if (remote) { return { ...thread, ...remote, @@ -9877,6 +10118,7 @@ var __webpack_modules__ = { hostName: remote.hostName ?? null }); } + if (remotes.length) merged.sort((a, b)=>Number(b.location === 'remote') - Number(a.location === 'remote')); const filtered = merged.filter((thread)=>{ if (!hostMatches(thread, host)) return false; if (!modelProviderMatches(thread, modelProvider)) return false; @@ -9884,7 +10126,7 @@ var __webpack_modules__ = { }); const limited = filtered.slice(0, limit); const result = { - backend: base.backend, + backend: remotes.length ? base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' : base.backend === 'app-server' ? 'app-server+remote-state' : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend : base.backend, limit, threads: limited, ...base.nextCursor !== undefined ? { @@ -10057,7 +10299,7 @@ var __webpack_modules__ = { const hostNames = collectHostNames(data); const out = []; const seen = new Set(); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of (0, _codex_remote_control_js__rspack_import_0.xr)(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; @@ -10109,12 +10351,12 @@ var __webpack_modules__ = { const data = (0, _codex_remote_control_js__rspack_import_0.IT)(env); if (data) { const hostNames = collectHostNames(data); - for (const key of Object.keys(data)){ + for (const [key, summary] of (0, _codex_remote_control_js__rspack_import_0.xr)(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; - const summary = data[key]; const hostName = hostNames.get(hostId) ?? extractHostName(summary) ?? null; + if (byHost.has(hostId)) continue; byHost.set(hostId, { hostId, hostName, @@ -10122,6 +10364,22 @@ var __webpack_modules__ = { threadCount: 0 }); } + const connections = data['codex-managed-remote-connections']; + if (Array.isArray(connections)) for (const entry of connections){ + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) continue; + const hostId = stringField(entry, [ + 'hostId' + ]); + if (hostId && !byHost.has(hostId)) byHost.set(hostId, { + hostId, + hostName: stringField(entry, [ + 'displayName', + 'alias' + ]), + location: 'remote', + threadCount: 0 + }); + } } for (const thread of remotes){ const existing = byHost.get(thread.hostId); @@ -10150,20 +10408,25 @@ var __webpack_modules__ = { } function collectHostNames(data) { const names = new Map(); - for (const [key, value] of Object.entries(data)){ + const connections = data['codex-managed-remote-connections']; + if (Array.isArray(connections)) for (const entry of connections){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + for (const [key, value] of (0, _codex_remote_control_js__rspack_import_0.xr)(data).flatMap(Object.entries)){ if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; if (!value || typeof value !== 'object') continue; if (Array.isArray(value)) { for (const entry of value){ const pair = hostNameFromEntry(entry); - if (pair) names.set(pair.hostId, pair.hostName); + if (pair && !names.has(pair.hostId)) names.set(pair.hostId, pair.hostName); } continue; } for (const [hostId, entry] of Object.entries(value)){ const fromEntry = hostNameFromEntry(entry); if (fromEntry) { - names.set(fromEntry.hostId, fromEntry.hostName); + if (!names.has(fromEntry.hostId)) names.set(fromEntry.hostId, fromEntry.hostName); continue; } const label = stringField(entry, [ @@ -10174,7 +10437,7 @@ var __webpack_modules__ = { 'label', 'title' ]); - if (label) names.set(hostId, label); + if (label && !names.has(hostId)) names.set(hostId, label); } } return names; @@ -10453,6 +10716,7 @@ var __webpack_modules__ = { const listThreadsSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() @@ -10471,7 +10735,7 @@ var __webpack_modules__ = { const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, - limit: zod__rspack_import_4.aig().int().min(1).max(2000).default(100), + limit: zod__rspack_import_4.aig().int().min(1).max(2000).optional(), full: zod__rspack_import_4.zMY().default(false), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); @@ -10563,6 +10827,7 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ limit: input.limit, + cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, groupBy: input.groupBy @@ -10617,7 +10882,7 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ threadId: input.threadId, - limit: input.limit, + limit: input.limit ?? (input.full ? 2000 : 100), full: input.full, openTimeoutMs: input.openTimeoutMs })); @@ -11348,7 +11613,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list hosts', - description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource', + description: 'Discover local, remote-control, and managed SSH hosts from Desktop state, including nested remote-thread summaries. Host names are null when Desktop has no display name. Providers come from paged app-server inventory and remote summaries. Result includes sources and discovery warnings.', annotations: { readOnlyHint: true }, @@ -11387,7 +11652,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.', + description: 'Page ChatGPT Desktop / Codex threads with cursor and nextCursor. Merges local app-server rows, CDP sidebar rows, and nested remote-control summaries. Discover dynamic host and modelProvider filters via chatgpt_desktop_list_hosts. Optional groupBy=host. Result reports the contributing backends and warnings.', annotations: { readOnlyHint: true }, @@ -11404,6 +11669,10 @@ var __webpack_modules__ = { type: 'number', description: 'Maximum threads (1-200).' }, + cursor: { + type: 'string', + description: 'Opaque nextCursor from a previous page.' + }, host: { type: 'string', description: 'Any string filter for machine/location. Reserved: "all" (default), "local". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.' @@ -11445,7 +11714,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host\'s app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.', + description: 'Read paged ChatGPT Desktop turns through app-server, including userText, assistantText, and completedAt as endedAt. Remote-only threads return REMOTE_THREAD_NOT_LOADED with hostId. CDP fallback reports complete:false and a warning when app-server fails. Result includes backend.', annotations: { readOnlyHint: true }, @@ -11470,7 +11739,7 @@ var __webpack_modules__ = { }, full: { type: 'boolean', - description: 'When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.' + description: 'When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.' }, openTimeoutMs: { type: 'number', @@ -23527,8 +23796,9 @@ var __webpack_modules__ = { ]; const WS_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; const WS_MAX_HEADER_BYTES = 16 * 1024; - const WS_MAX_MESSAGE_BYTES = 4 * 1024 * 1024; - const WS_MAX_BUFFER_BYTES = 8 * 1024 * 1024; + const WS_MAX_MESSAGE_BYTES = 16 * 1024 * 1024; + const WS_MAX_BUFFER_BYTES = 32 * 1024 * 1024; + const CODEX_SEND_MAX_BYTES = 4 * 1024 * 1024; const WS_MAX_WRITE_BYTES = 8 * 1024 * 1024; const CODEX_MAX_REQUESTS = 128; const CODEX_MAX_LISTENERS = 128; @@ -24719,7 +24989,7 @@ var __webpack_modules__ = { ].includes(whenBusy)) throw new RangeError("--when-busy must be reject, queue, or persistent steer"); if (whenBusy === "steer" && (typeof expectedTurnId !== "string" || !ID_PATTERN.test(expectedTurnId))) throw new RangeError("steer requires expectedTurnId"); threadId = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); - if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > WS_MAX_MESSAGE_BYTES) throw new RangeError("Message must contain text within 4 MiB"); + if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > CODEX_SEND_MAX_BYTES) throw new RangeError("Message must contain text within 4 MiB"); if (!envelope || typeof envelope.messageId !== "string" || !ID_PATTERN.test(envelope.messageId)) throw new RangeError("Invalid envelope messageId"); const validated = buildEnvelope({ correlationId: envelope.correlationId, @@ -25508,6 +25778,13 @@ var __webpack_modules__ = { return null; } } + function codexStateEntries(data) { + const nested = data?.['electron-persisted-atom-state']; + return [ + nested, + data + ].filter((value)=>value && typeof value === 'object' && !Array.isArray(value)); + } function findRemoteThreadHost(threadId, env = process.env) { let bare; try { @@ -25519,7 +25796,7 @@ var __webpack_modules__ = { const data = loadCodexGlobalState(env); if (!data) return null; const hostNames = collectHostNames(data); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; @@ -25552,20 +25829,20 @@ var __webpack_modules__ = { } function collectHostNames(data) { const names = new Map(); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)){ if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; if (!value || typeof value !== 'object') continue; if (Array.isArray(value)) { for (const entry of value){ const pair = hostNameFromEntry(entry); - if (pair) names.set(pair.hostId, pair.hostName); + if (pair && !names.has(pair.hostId)) names.set(pair.hostId, pair.hostName); } continue; } for (const [hostId, entry] of Object.entries(value)){ const fromEntry = hostNameFromEntry(entry); if (fromEntry) { - names.set(fromEntry.hostId, fromEntry.hostName); + if (!names.has(fromEntry.hostId)) names.set(fromEntry.hostId, fromEntry.hostName); continue; } const label = stringField(entry, [ @@ -25576,7 +25853,7 @@ var __webpack_modules__ = { 'label', 'title' ]); - if (label) names.set(hostId, label); + if (label && !names.has(hostId)) names.set(hostId, label); } } return names; @@ -25692,7 +25969,8 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { IT: ()=>loadCodexGlobalState, R3: ()=>mapRemoteThreadError, - Rg: ()=>RemoteThreadNotLoadedError1 + Rg: ()=>RemoteThreadNotLoadedError1, + xr: ()=>codexStateEntries }); }, "./src/core/codex/thread-id.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { @@ -27755,7 +28033,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource", + "description": "Discover local, remote-control, and managed SSH hosts from Desktop state, including nested remote-thread summaries. Host names are null when Desktop has no display name. Providers come from paged app-server inventory and remote summaries. Result includes sources and discovery warnings.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -27779,10 +28057,14 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.", + "description": "Page ChatGPT Desktop / Codex threads with cursor and nextCursor. Merges local app-server rows, CDP sidebar rows, and nested remote-control summaries. Discover dynamic host and modelProvider filters via chatgpt_desktop_list_hosts. Optional groupBy=host. Result reports the contributing backends and warnings.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "cursor": { + "description": "Opaque nextCursor from a previous page.", + "type": "string" + }, "groupBy": { "description": "When \"host\", also return groups[] keyed by host (grouping mode, not a host id).", "enum": [ @@ -27822,12 +28104,12 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.", + "description": "Read paged ChatGPT Desktop turns through app-server, including userText, assistantText, and completedAt as endedAt. Remote-only threads return REMOTE_THREAD_NOT_LOADED with hostId. CDP fallback reports complete:false and a warning when app-server fails. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { "full": { - "description": "When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.", + "description": "When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.", "type": "boolean" }, "limit": { diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index a216462..ee8200f 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -6521,9 +6521,10 @@ var __webpack_modules__ = { } const matched = []; let cursor; - for(let page = 0; page < 20 && matched.length < limit; page++){ + let exhausted = false; + for(let page = 0; page < 400 && matched.length < limit; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit: 200, + limit: 25, cursor, modelProviders }); @@ -6532,7 +6533,10 @@ var __webpack_modules__ = { if (threadMatchesQuery(mapped, needle)) matched.push(mapped); if (matched.length >= limit) break; } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + if (out.nextCursor == null || typeof out.nextCursor !== 'string') { + exhausted = true; + break; + } cursor = out.nextCursor; } return { @@ -6541,34 +6545,48 @@ var __webpack_modules__ = { query, nextCursor: null, threads: matched.slice(0, limit), - modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, + ...!exhausted && matched.length < limit ? { + warnings: [ + 'Search stopped after 400 app-server pages; results may be incomplete' + ] + } : {} }; } async function discoverModelProviders() { const providers = new Set(); + let threadCount = 0; let cursor; - for(let page = 0; page < 20; page++){ + let complete = false; + for(let page = 0; page < 400; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit: 200, + limit: 25, cursor, modelProviders: [] }); + threadCount += out.threads.length; for (const thread of out.threads){ if (typeof thread.modelProvider === 'string' && thread.modelProvider) { providers.add(thread.modelProvider); } } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + if (out.nextCursor == null || typeof out.nextCursor !== 'string') { + complete = true; + break; + } cursor = out.nextCursor; } return { providers: [ ...providers ].sort(), - source: 'thread/list-distinct' + source: 'thread/list-distinct', + threadCount, + complete }; } - async function appServerReadThread({ threadId, limit = 100, full = false }) { + async function appServerReadThread({ threadId, limit, full = false }) { + limit ??= full ? 2000 : 100; const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); if (remote) { @@ -6597,7 +6615,7 @@ var __webpack_modules__ = { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { const meta = await readThreadMetadata(client, bare); - const turns = await listTurnsFull(client, bare, { + const { turns, complete } = await listTurnsFull(client, bare, { limit, full }); @@ -6607,6 +6625,7 @@ var __webpack_modules__ = { backend: 'app-server', limit, full, + complete, title: meta.title, cwd: meta.cwd, status: meta.status, @@ -6695,12 +6714,13 @@ var __webpack_modules__ = { let itemsView = true; let method = 'thread/turns/list'; const seen = new Set(); + let complete = false; while(collected.length < limit){ let result; try { result = await client.request(method, { threadId, - limit: Math.min(100, limit - collected.length), + limit: Math.min(10, limit - collected.length), sortDirection: full ? 'asc' : 'desc', ...method === 'thread/turns/list' && itemsView ? { itemsView: 'full' @@ -6723,7 +6743,10 @@ var __webpack_modules__ = { } if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); collected.push(...result.data); - if (result.nextCursor == null) break; + if (result.nextCursor == null) { + complete = true; + break; + } if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { throw new Error(`${method} returned an invalid or repeated cursor`); } @@ -6731,7 +6754,10 @@ var __webpack_modules__ = { cursor = result.nextCursor; } const turns = normalizeTurns(collected.slice(0, limit)); - return full ? turns : turns.reverse(); + return { + turns: full ? turns : turns.reverse(), + complete + }; } function normalizeTurns(raw) { const turns = []; @@ -6787,7 +6813,7 @@ var __webpack_modules__ = { assistantText } : {}, startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, - endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + endedAt: typeof row.completedAt === 'number' ? row.completedAt : typeof row.endedAt === 'number' ? row.endedAt : null }; } function normalizeLeafItem(id, row) { @@ -6803,12 +6829,13 @@ var __webpack_modules__ = { role, text, startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, - endedAt: typeof row.endedAt === 'number' ? row.endedAt : null + endedAt: typeof row.completedAt === 'number' ? row.completedAt : typeof row.endedAt === 'number' ? row.endedAt : null }; } function extractText(row) { if (typeof row.text === 'string') return row.text; if (typeof row.content === 'string') return row.content; + if (Array.isArray(row.content)) return row.content.filter((part)=>Boolean(part) && typeof part === 'object' && !Array.isArray(part)).map((part)=>typeof part.text === 'string' ? part.text : '').filter(Boolean).join('\n'); if (typeof row.preview === 'string') return row.preview; return ''; } @@ -6915,7 +6942,8 @@ var __webpack_modules__ = { turns, backend: 'cdp', limit, - full + full, + complete: false }; } async sendMessage({ threadId, text, project, openTimeoutMs = 90000 }) { @@ -7229,6 +7257,7 @@ var __webpack_modules__ = { const project = projectFor(row); out.push({ threadId, + hostId: row.getAttribute('data-app-action-sidebar-thread-host-id') || null, title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', @@ -7257,6 +7286,26 @@ var __webpack_modules__ = { if (!row) return { ok: false, error: 'thread-not-found' }; row.click(); return { ok: true, threadId: row.getAttribute(${JSON.stringify(ATTR.threadId)}) || candidates[0] }; + })()`; + } + function navigateToThreadExpression(threadId) { + const bare = durableThreadKey(threadId); + return `(async () => { + const root = window.__codexRoot?._internalRoot?.current; + const queue = [root]; + let scanned = 0; + while (queue.length && scanned++ < 10000) { + const fiber = queue.shift(); + if (!fiber) continue; + const router = fiber.memoizedProps?.router; + if (router?.navigate && router?.state?.location) { + await router.navigate(${JSON.stringify(`/local/${bare}`)}); + return { ok: true, via: 'router' }; + } + if (fiber.child) queue.push(fiber.child); + if (fiber.sibling) queue.push(fiber.sibling); + } + return { ok: false, error: 'router-not-found' }; })()`; } function startNewChatExpression(project) { @@ -7266,8 +7315,11 @@ var __webpack_modules__ = { if (projectSel) { const preferred = document.querySelector(projectSel); if (preferred) { - preferred.click(); - return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; + const row = preferred.closest('.group') || preferred.parentElement; + row?.scrollIntoView({ block: 'center' }); + const rowBox = row?.getBoundingClientRect(); + return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)}, + hoverX: rowBox?.left + rowBox?.width / 2, hoverY: rowBox?.top + rowBox?.height / 2 }; } return { ok: false, error: 'project-not-found' }; } @@ -7276,6 +7328,15 @@ var __webpack_modules__ = { if (!fallback) return { ok: false, error: 'new-chat-not-found' }; fallback.click(); return { ok: true, via: 'fallback' }; + })()`; + } + function projectButtonBoxExpression(project) { + return `(() => { + const button = document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); + if (!button) return null; + const box = button.getBoundingClientRect(); + return { x: box.left + box.width / 2, y: box.top + box.height / 2, + visible: box.width > 0 && box.height > 0 && getComputedStyle(button.parentElement).opacity !== '0' }; })()`; } const LOADING_TASK_GONE_EXPRESSION = `(() => { @@ -7289,6 +7350,9 @@ var __webpack_modules__ = { const text = (surface.innerText || '').replace(/\\u2026/g, '…'); return !text.includes(${JSON.stringify(LOADING_TASK_TEXT)}); })()`; + const ARCHIVED_THREAD_EXPRESSION = `(() => Array.from(document.querySelectorAll('main')) + .some((main) => (main.innerText || '').includes('This task is archived') + && (main.innerText || '').includes('Unarchive this task to open it')))()`; const FOCUS_COMPOSER_EXPRESSION = `(() => { const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); if (!composer) return { ok: false, error: 'composer-not-found' }; @@ -7393,27 +7457,60 @@ var __webpack_modules__ = { pinned: Boolean(row.pinned), selected: Boolean(row.selected), kind: String(row.kind ?? 'unknown'), + ...row.hostId ? { + hostId: row.hostId, + location: row.hostId === 'local' ? 'local' : 'remote' + } : {}, ...row.project ? { project: String(row.project) } : {} })); } async function openThreadInDom(session, sessionId, threadId) { + const current = await readConversationIdFromDom(session, sessionId); + if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; + if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + const rows = await listThreadsFromDom(session, sessionId, { + limit: 200 + }); + if (rows.some((row)=>row.selected && row.threadId === threadId)) return; + } const result = await session.evaluate(openThreadExpression(threadId), { sessionId }); if (!result?.ok) { + if (result?.error === 'thread-not-found' && !(0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + const navigated = await session.evaluate(navigateToThreadExpression(threadId), { + sessionId + }); + if (navigated?.ok) return; + } throw new Error(result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` : `Failed to open ChatGPT Desktop thread ${threadId}`); } } async function waitForLoadingTaskGone(session, sessionId, { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS, threadId } = {}) { const deadline = Date.now() + timeoutMs; + let loadingGone = false; + let lastConversationId = ''; + let archivedSince = null; while(Date.now() < deadline){ + if (threadId && threadId !== 'new' && await session.evaluate(ARCHIVED_THREAD_EXPRESSION, { + sessionId + }) === true) { + archivedSince ??= Date.now(); + if (Date.now() - archivedSince >= 500) { + throw new Error(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived; unarchive it in Desktop before opening`); + } + } else { + archivedSince = null; + } const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { sessionId }); + loadingGone ||= gone; if (gone) { const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; + lastConversationId = current; if (!threadId) return; if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { @@ -7425,7 +7522,7 @@ var __webpack_modules__ = { } await delay(250); } - throw new Error(`ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); + throw new Error(loadingGone ? `ChatGPT Desktop timed out waiting for conversation ${JSON.stringify(threadId)}; displayed conversation ${JSON.stringify(lastConversationId)} after ${timeoutMs}ms` : `ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); } async function startNewChatInDom(session, sessionId, { project } = {}) { const result = await session.evaluate(startNewChatExpression(project), { @@ -7434,6 +7531,52 @@ var __webpack_modules__ = { if (!result?.ok) { throw new Error(project ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` : 'ChatGPT Desktop "New chat" button not found'); } + if (result.via === 'project') { + if (![ + result.hoverX, + result.hoverY + ].every(Number.isFinite)) { + throw new Error(`ChatGPT Desktop project button has no visible box for ${JSON.stringify(project)}`); + } + await session.send('Input.dispatchMouseEvent', { + type: 'mouseMoved', + x: result.hoverX, + y: result.hoverY + }, { + sessionId + }); + const button = await session.evaluate(projectButtonBoxExpression(project), { + sessionId + }); + if (!button?.visible || !Number.isFinite(button.x) || !Number.isFinite(button.y)) { + throw new Error(`ChatGPT Desktop project button did not appear after hover for ${JSON.stringify(project)}`); + } + await session.send('Input.dispatchMouseEvent', { + type: 'mouseMoved', + x: button.x, + y: button.y + }, { + sessionId + }); + await session.send('Input.dispatchMouseEvent', { + type: 'mousePressed', + x: button.x, + y: button.y, + button: 'left', + clickCount: 1 + }, { + sessionId + }); + await session.send('Input.dispatchMouseEvent', { + type: 'mouseReleased', + x: button.x, + y: button.y, + button: 'left', + clickCount: 1 + }, { + sessionId + }); + } return { via: result.via ?? 'unknown' }; @@ -7580,16 +7723,18 @@ var __webpack_modules__ = { } async function readTurnsFromDom(session, sessionId, { limit = 100, full = false, threadId, idleWheels = DEFAULT_FULL_READ_IDLE_WHEELS, maxWheels = DEFAULT_FULL_READ_MAX_WHEELS } = {}) { const collected = new Map(); + const order1 = []; const ingest = async ()=>{ + const older = []; for (const turn of (await harvestVisibleTurns(session, sessionId))){ + if (!collected.has(turn.turnKey)) older.push(turn.turnKey); collected.set(turn.turnKey, turn); } + order1.unshift(...older); }; await ingest(); if (!full) { - const visible = [ - ...collected.values() - ]; + const visible = order1.map((key)=>collected.get(key)); return limit > 0 ? visible.slice(-limit) : visible; } let idle = 0; @@ -7618,9 +7763,7 @@ var __webpack_modules__ = { } if (threadId && collected.has(threadId)) break; } - const all = [ - ...collected.values() - ]; + const all = order1.map((key)=>collected.get(key)); return limit > 0 ? all.slice(0, limit) : all; } function delay(ms) { @@ -7890,6 +8033,8 @@ var __webpack_modules__ = { listHosts: _remote_threads_js__rspack_import_4.Kl, discoverModelProviders: _app_server_fallback_js__rspack_import_1.X }; + const REMOTE_PAGE_CURSOR = 'desktop-remote-page:'; + const APP_START_CURSOR = 'desktop-app-start'; class ChatGptDesktopFacade { #cdp; #port; @@ -7920,23 +8065,21 @@ var __webpack_modules__ = { const limit = options.limit ?? 50; const host = normalizeHostFilter(options.host); const modelProviders = modelProvidersFromFilter(options.modelProvider); - let appList = null; - let appError; - try { - appList = await this.#fallbacks.listThreads({ - limit, - modelProviders - }); - } catch (error) { - appError = error; + const remoteOffset = options.cursor?.startsWith(REMOTE_PAGE_CURSOR) ? Number(options.cursor.slice(REMOTE_PAGE_CURSOR.length)) : null; + if (remoteOffset !== null && (!Number.isSafeInteger(remoteOffset) || remoteOffset < 1)) { + throw new Error('Invalid ChatGPT Desktop remote page cursor'); } + const inventoryPage = !options.cursor || remoteOffset !== null; + const remotes = inventoryPage ? this.#listRemotes() : []; let cdpList = null; let cdpError; try { - await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads({ - limit - }); + if (inventoryPage) { + await this.#ensureCdp(); + cdpList = await this.#cdp.listThreads({ + limit: 200 + }); + } } catch (error) { if (isCdpFailure(error)) { this.#cdpConnected = false; @@ -7944,33 +8087,87 @@ var __webpack_modules__ = { cdpError = error; } } - const remotes = this.#listRemotes(); + if (inventoryPage && host !== 'local') { + const remoteInventory = finalizeThreadList({ + backend: cdpList?.backend ?? 'remote-state', + limit: 10000, + threads: cdpList?.threads.filter((thread)=>thread.location === 'remote') ?? [] + }, { + limit: 10000, + host, + modelProvider: options.modelProvider, + remotes + }); + const offset = remoteOffset ?? 0; + if (remoteOffset !== null || remoteInventory.threads.length >= limit) { + const page = remoteInventory.threads.slice(offset, offset + limit); + const nextOffset = offset + page.length; + const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; + return { + ...remoteInventory, + threads: page, + limit, + nextCursor, + ...options.groupBy === 'host' ? { + groupBy: 'host', + groups: groupThreadsByHost(page) + } : {} + }; + } + } + const remoteKeys = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; + const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); + let appList = null; + let appError; + try { + appList = await this.#fallbacks.listThreads({ + limit: appLimit, + cursor: options.cursor === APP_START_CURSOR ? undefined : options.cursor, + modelProviders + }); + } catch (error) { + appError = error; + } let base = null; if (appList && cdpList) base = mergeThreadLists(appList, cdpList); else if (appList) base = appList; else if (cdpList) base = cdpList; else if (remotes.length) base = { - backend: 'app-server', + backend: 'remote-state', limit, threads: [] }; else if (cdpError) throw cdpError; else if (appError) throw appError; else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); - return finalizeThreadList(base, { + const result = finalizeThreadList(base, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes }); + const withCursor = host === 'all' || host === 'local' ? result : { + ...result, + nextCursor: null + }; + return appError ? { + ...withCursor, + warnings: [ + `App-server list failed: ${appError instanceof Error ? appError.message : String(appError)}` + ] + } : withCursor; } async listHosts() { const remotes = this.#listRemotes(); + const cdpRows = typeof this.#cdp.listThreads === 'function' ? (await this.#tryCdpList({ + limit: 200 + }))?.threads ?? [] : []; let localThreadCount = 0; try { const local = await this.#fallbacks.listThreads({ - limit: 200, + limit: 25, modelProviders: [] }); localThreadCount = local.threads.length; @@ -8003,11 +8200,28 @@ var __webpack_modules__ = { }); } } - const hostsSource = 'remote-thread-summaries-v3+local'; + for (const thread of cdpRows){ + if (thread.location !== 'remote' || !thread.hostId) continue; + if (!byId.has(thread.hostId)) byId.set(thread.hostId, { + hostId: thread.hostId, + hostName: thread.hostName ?? null, + location: 'remote', + threadCount: 0 + }); + } + const hostsSource = 'local+remote-thread-summaries-v3+managed-connections' + (cdpRows.length ? '+cdp' : ''); const remoteCounts = new Map(); for (const thread of remotes){ remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); } + const remoteIds = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + for (const thread of cdpRows){ + if (thread.location !== 'remote' || !thread.hostId) continue; + const id = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; + if (remoteIds.has(id)) continue; + remoteIds.add(id); + remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + } const withCounts = [ ...byId.values() ].map((host)=>host.hostId === 'local' ? { @@ -8023,6 +8237,7 @@ var __webpack_modules__ = { }); let modelProviders = []; let modelProvidersSource = 'thread/list-distinct'; + const warnings = []; try { const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_1.X; const discovered = await discover(); @@ -8030,7 +8245,10 @@ var __webpack_modules__ = { ...discovered.providers ]; modelProvidersSource = discovered.source; - } catch { + if (typeof discovered.threadCount === 'number') localThreadCount = discovered.threadCount; + if (discovered.complete === false) warnings.push('Provider discovery stopped before the final app-server page'); + } catch (error) { + warnings.push(`Model provider discovery failed: ${error instanceof Error ? error.message : String(error)}`); modelProviders = [ ...new Set(remotes.map((thread)=>thread.modelProvider).filter((value)=>typeof value === 'string' && Boolean(value))) ].sort(); @@ -8043,11 +8261,17 @@ var __webpack_modules__ = { ]) ].sort(); return { - hosts: withCounts, + hosts: withCounts.map((host)=>host.hostId === 'local' ? { + ...host, + threadCount: localThreadCount + } : host), hostsSource, modelProviders, modelProvidersSource, - backend: 'app-server' + backend: cdpRows.length ? remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp' : remotes.length ? 'app-server+remote-state' : 'app-server', + ...warnings.length ? { + warnings + } : {} }; } async searchThreads(options) { @@ -8076,13 +8300,14 @@ var __webpack_modules__ = { query: options.query, threads: withRemotes.threads.filter((thread)=>threadMatchesQuery(thread, needle)) }; - return finalizeThreadList(filtered, { + const result = finalizeThreadList(filtered, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: [] }); + return result; } catch (appError) { const cdpList = await this.#tryCdpList({ limit @@ -8098,17 +8323,23 @@ var __webpack_modules__ = { query: options.query, threads: (cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) }; - return finalizeThreadList(filtered, { + const result = finalizeThreadList(filtered, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) }); + return { + ...result, + warnings: [ + `App-server search failed: ${appError instanceof Error ? appError.message : String(appError)}` + ] + }; } } async readThread(options) { - const limit = options.limit ?? 100; + const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { await this.#ensureCdp(); @@ -8128,11 +8359,18 @@ var __webpack_modules__ = { if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; - return this.#cdp.readThread({ + const fallback = await this.#cdp.readThread({ ...options, limit, full }); + return { + ...fallback, + complete: false, + warnings: [ + `App-server read failed: ${appError instanceof Error ? appError.message : String(appError)}` + ] + }; } } async sendMessage(options) { @@ -8157,13 +8395,13 @@ var __webpack_modules__ = { reachable: false }; } - const reachable = cdpStatus.reachable || Boolean(appServerFallback?.reachable); + const reachable = cdpStatus.reachable; return { ...cdpStatus, port: this.#port, appServerFallback, reachable, - message: cdpStatus.reachable ? cdpStatus.message : appServerFallback?.reachable ? 'CDP unreachable; Codex app-server available for list/search/read' : cdpStatus.message, + message: cdpStatus.reachable ? cdpStatus.message : cdpStatus.message, exitCode: reachable ? 0 : 1 }; } @@ -8231,7 +8469,10 @@ var __webpack_modules__ = { pinned: withLocal.pinned || cdp.pinned, selected: cdp.selected, kind: cdp.kind || withLocal.kind, - project: cdp.project ?? withLocal.project + project: cdp.project ?? withLocal.project, + location: cdp.location === 'remote' ? 'remote' : withLocal.location, + hostId: cdp.location === 'remote' ? cdp.hostId ?? null : withLocal.hostId, + hostName: cdp.location === 'remote' ? cdp.hostName ?? null : withLocal.hostName }; }); for (const thread of cdpList.threads){ @@ -8239,7 +8480,7 @@ var __webpack_modules__ = { merged.push(thread); } return { - backend: appList.backend, + backend: 'app-server+cdp', limit: appList.limit, nextCursor: appList.nextCursor, ...appList.query !== undefined ? { @@ -8255,7 +8496,7 @@ var __webpack_modules__ = { ])); const locals = base.threads.map((thread)=>{ const remote = remoteById.get((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId); - if (remote && thread.location === undefined) { + if (remote) { return { ...thread, ...remote, @@ -8285,6 +8526,7 @@ var __webpack_modules__ = { hostName: remote.hostName ?? null }); } + if (remotes.length) merged.sort((a, b)=>Number(b.location === 'remote') - Number(a.location === 'remote')); const filtered = merged.filter((thread)=>{ if (!hostMatches(thread, host)) return false; if (!modelProviderMatches(thread, modelProvider)) return false; @@ -8292,7 +8534,7 @@ var __webpack_modules__ = { }); const limited = filtered.slice(0, limit); const result = { - backend: base.backend, + backend: remotes.length ? base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' : base.backend === 'app-server' ? 'app-server+remote-state' : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend : base.backend, limit, threads: limited, ...base.nextCursor !== undefined ? { @@ -8465,7 +8707,7 @@ var __webpack_modules__ = { const hostNames = collectHostNames(data); const out = []; const seen = new Set(); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of (0, _codex_remote_control_js__rspack_import_0.xr)(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; @@ -8517,12 +8759,12 @@ var __webpack_modules__ = { const data = (0, _codex_remote_control_js__rspack_import_0.IT)(env); if (data) { const hostNames = collectHostNames(data); - for (const key of Object.keys(data)){ + for (const [key, summary] of (0, _codex_remote_control_js__rspack_import_0.xr)(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; - const summary = data[key]; const hostName = hostNames.get(hostId) ?? extractHostName(summary) ?? null; + if (byHost.has(hostId)) continue; byHost.set(hostId, { hostId, hostName, @@ -8530,6 +8772,22 @@ var __webpack_modules__ = { threadCount: 0 }); } + const connections = data['codex-managed-remote-connections']; + if (Array.isArray(connections)) for (const entry of connections){ + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) continue; + const hostId = stringField(entry, [ + 'hostId' + ]); + if (hostId && !byHost.has(hostId)) byHost.set(hostId, { + hostId, + hostName: stringField(entry, [ + 'displayName', + 'alias' + ]), + location: 'remote', + threadCount: 0 + }); + } } for (const thread of remotes){ const existing = byHost.get(thread.hostId); @@ -8558,20 +8816,25 @@ var __webpack_modules__ = { } function collectHostNames(data) { const names = new Map(); - for (const [key, value] of Object.entries(data)){ + const connections = data['codex-managed-remote-connections']; + if (Array.isArray(connections)) for (const entry of connections){ + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + for (const [key, value] of (0, _codex_remote_control_js__rspack_import_0.xr)(data).flatMap(Object.entries)){ if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; if (!value || typeof value !== 'object') continue; if (Array.isArray(value)) { for (const entry of value){ const pair = hostNameFromEntry(entry); - if (pair) names.set(pair.hostId, pair.hostName); + if (pair && !names.has(pair.hostId)) names.set(pair.hostId, pair.hostName); } continue; } for (const [hostId, entry] of Object.entries(value)){ const fromEntry = hostNameFromEntry(entry); if (fromEntry) { - names.set(fromEntry.hostId, fromEntry.hostName); + if (!names.has(fromEntry.hostId)) names.set(fromEntry.hostId, fromEntry.hostName); continue; } const label = stringField(entry, [ @@ -8582,7 +8845,7 @@ var __webpack_modules__ = { 'label', 'title' ]); - if (label) names.set(hostId, label); + if (label && !names.has(hostId)) names.set(hostId, label); } } return names; @@ -8861,6 +9124,7 @@ var __webpack_modules__ = { const listThreadsSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() @@ -8879,7 +9143,7 @@ var __webpack_modules__ = { const readThreadSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId, - limit: zod__rspack_import_4.aig().int().min(1).max(2000).default(100), + limit: zod__rspack_import_4.aig().int().min(1).max(2000).optional(), full: zod__rspack_import_4.zMY().default(false), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); @@ -8971,6 +9235,7 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.listThreads({ limit: input.limit, + cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, groupBy: input.groupBy @@ -9025,7 +9290,7 @@ var __webpack_modules__ = { try { const out = await withAdapter(input.port, (adapter)=>adapter.readThread({ threadId: input.threadId, - limit: input.limit, + limit: input.limit ?? (input.full ? 2000 : 100), full: input.full, openTimeoutMs: input.openTimeoutMs })); @@ -9756,7 +10021,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list hosts', - description: 'Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource', + description: 'Discover local, remote-control, and managed SSH hosts from Desktop state, including nested remote-thread summaries. Host names are null when Desktop has no display name. Providers come from paged app-server inventory and remote summaries. Result includes sources and discovery warnings.', annotations: { readOnlyHint: true }, @@ -9795,7 +10060,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.', + description: 'Page ChatGPT Desktop / Codex threads with cursor and nextCursor. Merges local app-server rows, CDP sidebar rows, and nested remote-control summaries. Discover dynamic host and modelProvider filters via chatgpt_desktop_list_hosts. Optional groupBy=host. Result reports the contributing backends and warnings.', annotations: { readOnlyHint: true }, @@ -9812,6 +10077,10 @@ var __webpack_modules__ = { type: 'number', description: 'Maximum threads (1-200).' }, + cursor: { + type: 'string', + description: 'Opaque nextCursor from a previous page.' + }, host: { type: 'string', description: 'Any string filter for machine/location. Reserved: "all" (default), "local". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.' @@ -9853,7 +10122,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host\'s app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.', + description: 'Read paged ChatGPT Desktop turns through app-server, including userText, assistantText, and completedAt as endedAt. Remote-only threads return REMOTE_THREAD_NOT_LOADED with hostId. CDP fallback reports complete:false and a warning when app-server fails. Result includes backend.', annotations: { readOnlyHint: true }, @@ -9878,7 +10147,7 @@ var __webpack_modules__ = { }, full: { type: 'boolean', - description: 'When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.' + description: 'When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.' }, openTimeoutMs: { type: 'number', @@ -59263,7 +59532,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource", + "description": "Discover local, remote-control, and managed SSH hosts from Desktop state, including nested remote-thread summaries. Host names are null when Desktop has no display name. Providers come from paged app-server inventory and remote summaries. Result includes sources and discovery warnings.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -59286,10 +59555,14 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.", + "description": "Page ChatGPT Desktop / Codex threads with cursor and nextCursor. Merges local app-server rows, CDP sidebar rows, and nested remote-control summaries. Discover dynamic host and modelProvider filters via chatgpt_desktop_list_hosts. Optional groupBy=host. Result reports the contributing backends and warnings.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "cursor": { + "description": "Opaque nextCursor from a previous page.", + "type": "string" + }, "groupBy": { "description": "When \"host\", also return groups[] keyed by host (grouping mode, not a host id).", "enum": [ @@ -59328,12 +59601,12 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host's app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.", + "description": "Read paged ChatGPT Desktop turns through app-server, including userText, assistantText, and completedAt as endedAt. Remote-only threads return REMOTE_THREAD_NOT_LOADED with hostId. CDP fallback reports complete:false and a warning when app-server fails. Result includes backend.", "inputJsonSchema": { "additionalProperties": false, "properties": { "full": { - "description": "When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.", + "description": "When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.", "type": "boolean" }, "limit": { @@ -60567,8 +60840,9 @@ var __webpack_modules__ = { ]; const WS_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; const WS_MAX_HEADER_BYTES = 16 * 1024; - const WS_MAX_MESSAGE_BYTES = 4 * 1024 * 1024; - const WS_MAX_BUFFER_BYTES = 8 * 1024 * 1024; + const WS_MAX_MESSAGE_BYTES = 16 * 1024 * 1024; + const WS_MAX_BUFFER_BYTES = 32 * 1024 * 1024; + const CODEX_SEND_MAX_BYTES = 4 * 1024 * 1024; const WS_MAX_WRITE_BYTES = 8 * 1024 * 1024; const CODEX_MAX_REQUESTS = 128; const CODEX_MAX_LISTENERS = 128; @@ -61759,7 +62033,7 @@ var __webpack_modules__ = { ].includes(whenBusy)) throw new RangeError("--when-busy must be reject, queue, or persistent steer"); if (whenBusy === "steer" && (typeof expectedTurnId !== "string" || !ID_PATTERN.test(expectedTurnId))) throw new RangeError("steer requires expectedTurnId"); threadId = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); - if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > WS_MAX_MESSAGE_BYTES) throw new RangeError("Message must contain text within 4 MiB"); + if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > CODEX_SEND_MAX_BYTES) throw new RangeError("Message must contain text within 4 MiB"); if (!envelope || typeof envelope.messageId !== "string" || !ID_PATTERN.test(envelope.messageId)) throw new RangeError("Invalid envelope messageId"); const validated = buildEnvelope({ correlationId: envelope.correlationId, @@ -62548,6 +62822,13 @@ var __webpack_modules__ = { return null; } } + function codexStateEntries(data) { + const nested = data?.['electron-persisted-atom-state']; + return [ + nested, + data + ].filter((value)=>value && typeof value === 'object' && !Array.isArray(value)); + } function findRemoteThreadHost(threadId, env = process.env) { let bare; try { @@ -62559,7 +62840,7 @@ var __webpack_modules__ = { const data = loadCodexGlobalState(env); if (!data) return null; const hostNames = collectHostNames(data); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; @@ -62592,20 +62873,20 @@ var __webpack_modules__ = { } function collectHostNames(data) { const names = new Map(); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)){ if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; if (!value || typeof value !== 'object') continue; if (Array.isArray(value)) { for (const entry of value){ const pair = hostNameFromEntry(entry); - if (pair) names.set(pair.hostId, pair.hostName); + if (pair && !names.has(pair.hostId)) names.set(pair.hostId, pair.hostName); } continue; } for (const [hostId, entry] of Object.entries(value)){ const fromEntry = hostNameFromEntry(entry); if (fromEntry) { - names.set(fromEntry.hostId, fromEntry.hostName); + if (!names.has(fromEntry.hostId)) names.set(fromEntry.hostId, fromEntry.hostName); continue; } const label = stringField(entry, [ @@ -62616,7 +62897,7 @@ var __webpack_modules__ = { 'label', 'title' ]); - if (label) names.set(hostId, label); + if (label && !names.has(hostId)) names.set(hostId, label); } } return names; @@ -62732,7 +63013,8 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { IT: ()=>loadCodexGlobalState, R3: ()=>mapRemoteThreadError, - Rg: ()=>RemoteThreadNotLoadedError1 + Rg: ()=>RemoteThreadNotLoadedError1, + xr: ()=>codexStateEntries }); }, "./src/core/codex/thread-id.js" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { diff --git a/artifact/scripts/gbot-relay.mjs b/artifact/scripts/gbot-relay.mjs index f9e86d4..88c43d1 100644 --- a/artifact/scripts/gbot-relay.mjs +++ b/artifact/scripts/gbot-relay.mjs @@ -22144,8 +22144,9 @@ var __webpack_modules__ = { ]; const WS_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; const WS_MAX_HEADER_BYTES = 16 * 1024; - const WS_MAX_MESSAGE_BYTES = 4 * 1024 * 1024; - const WS_MAX_BUFFER_BYTES = 8 * 1024 * 1024; + const WS_MAX_MESSAGE_BYTES = 16 * 1024 * 1024; + const WS_MAX_BUFFER_BYTES = 32 * 1024 * 1024; + const CODEX_SEND_MAX_BYTES = 4 * 1024 * 1024; const WS_MAX_WRITE_BYTES = 8 * 1024 * 1024; const CODEX_MAX_REQUESTS = 128; const CODEX_MAX_LISTENERS = 128; @@ -23336,7 +23337,7 @@ var __webpack_modules__ = { ].includes(whenBusy)) throw new RangeError("--when-busy must be reject, queue, or persistent steer"); if (whenBusy === "steer" && (typeof expectedTurnId !== "string" || !ID_PATTERN.test(expectedTurnId))) throw new RangeError("steer requires expectedTurnId"); threadId = (0, _codex_thread_id_js__rspack_import_11.SX)(threadId); - if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > WS_MAX_MESSAGE_BYTES) throw new RangeError("Message must contain text within 4 MiB"); + if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > CODEX_SEND_MAX_BYTES) throw new RangeError("Message must contain text within 4 MiB"); if (!envelope || typeof envelope.messageId !== "string" || !ID_PATTERN.test(envelope.messageId)) throw new RangeError("Invalid envelope messageId"); const validated = buildEnvelope({ correlationId: envelope.correlationId, @@ -24122,6 +24123,13 @@ var __webpack_modules__ = { return null; } } + function codexStateEntries(data) { + const nested = data?.['electron-persisted-atom-state']; + return [ + nested, + data + ].filter((value)=>value && typeof value === 'object' && !Array.isArray(value)); + } function findRemoteThreadHost(threadId, env = process.env) { let bare; try { @@ -24133,7 +24141,7 @@ var __webpack_modules__ = { const data = loadCodexGlobalState(env); if (!data) return null; const hostNames = collectHostNames(data); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)){ const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; @@ -24166,20 +24174,20 @@ var __webpack_modules__ = { } function collectHostNames(data) { const names = new Map(); - for (const [key, value] of Object.entries(data)){ + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)){ if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; if (!value || typeof value !== 'object') continue; if (Array.isArray(value)) { for (const entry of value){ const pair = hostNameFromEntry(entry); - if (pair) names.set(pair.hostId, pair.hostName); + if (pair && !names.has(pair.hostId)) names.set(pair.hostId, pair.hostName); } continue; } for (const [hostId, entry] of Object.entries(value)){ const fromEntry = hostNameFromEntry(entry); if (fromEntry) { - names.set(fromEntry.hostId, fromEntry.hostName); + if (!names.has(fromEntry.hostId)) names.set(fromEntry.hostId, fromEntry.hostName); continue; } const label = stringField(entry, [ @@ -24190,7 +24198,7 @@ var __webpack_modules__ = { 'label', 'title' ]); - if (label) names.set(hostId, label); + if (label && !names.has(hostId)) names.set(hostId, label); } } return names; diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index 7b926a3..c60235d 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -33,6 +33,7 @@ Override the port with `CHATGPT_DESKTOP_CDP_PORT` or `--port`. gbot chatgpt-desktop status gbot chatgpt-desktop hosts # discover hostIds + modelProviders at runtime gbot chatgpt-desktop threads --limit 20 +gbot chatgpt-desktop threads --limit 20 --cursor gbot chatgpt-desktop threads --host local gbot chatgpt-desktop threads --host --model-provider gbot chatgpt-desktop search "launch" --host all @@ -116,11 +117,18 @@ Hosts are discovered dynamically — do not hardcode them: 1. Always include `local` 2. Every `remote-thread-summaries-v3:` key in - `~/.codex/.codex-global-state.json`, with friendly names and thread counts + `~/.codex/.codex-global-state.json`, including keys under + `electron-persisted-atom-state`, with thread counts +3. Managed SSH connections in `codex-managed-remote-connections` + +`hostName` is the Desktop display name when present, otherwise `null`. +Project labels are not used as machine names. CDP sidebar rows expose their +host id, and matching remote summaries supply ownership when available. `modelProviders` combines distinct `modelProvider` values from `thread/list` (`modelProviders: []`) and remote summaries. `modelProvidersSource` names the local discovery path; if unavailable, remote summaries still contribute. +Failures and page-cap truncation appear in `warnings`. Explicit provider filters exclude rows whose provider is unknown. ### Remote-control threads @@ -143,10 +151,21 @@ skipped. | `list_threads` | merge selected / UI overlay | primary inventory + remote summaries | | `search_threads` | merge selected when connected | primary (list + filter, includes remotes) | | `read_thread` | DOM harvest / wheel **fallback only** (local) | primary; remote → typed error + host hint | -| `open_thread` (selected) | click sidebar row | **not used** (resume attaches) | +| `open_thread` (selected) | click sidebar row or navigate through Desktop's memory router by conversation id | **not used** (resume attaches) | | `send` / new-thread-in-project | composer + Enter / project button | **not used** | | `wait_reply` | Stop gone + final-assistant | **not used** | +`status.reachable` and its process exit code report CDP availability; the +app-server probe is separate. List/search results report `app-server+cdp` +when both contribute, and append `remote-state` when remote summaries +contribute. `read_thread` returns `complete` and `warnings` so a CDP fallback +cannot be mistaken for a complete app-server read. A turn may contain both +`userText` and `assistantText`; `endedAt` uses the app-server `completedAt`. +Full reads page from the oldest turn until completion, with a default cap of +2000 turns; an explicit `limit` can lower that cap. +Archived conversations can be read through app-server, but Desktop requires +an explicit unarchive before opening them for interaction. + ## Target selection Prefer CDP `Target.getTargets`. The main window is `type: "page"` with URL diff --git a/src/cli/chatgpt-desktop/read.tsx b/src/cli/chatgpt-desktop/read.tsx index ee3320a..3ae852e 100644 --- a/src/cli/chatgpt-desktop/read.tsx +++ b/src/cli/chatgpt-desktop/read.tsx @@ -17,7 +17,7 @@ export const config = { additionalProperties: false, properties: { full: { default: false, type: 'boolean' }, - limit: { default: 100, type: 'number' }, + limit: { description: 'Recent default 100; full default 2000', type: 'number' }, openTimeoutMs: { default: 90000, type: 'number' }, port: { type: 'number' }, threadId: { type: 'string' }, @@ -31,7 +31,7 @@ export const config = { export const inputSchema = z .object({ full: z.boolean().default(false), - limit: z.number().int().min(1).max(2000).default(100), + limit: z.number().int().min(1).max(2000).optional(), openTimeoutMs: z.number().int().min(1).max(600_000).default(90_000), port: z.number().int().min(1).max(65535).optional(), threadId: z.string().min(1).max(256), diff --git a/src/cli/chatgpt-desktop/threads.tsx b/src/cli/chatgpt-desktop/threads.tsx index 7405d6e..8c4170c 100644 --- a/src/cli/chatgpt-desktop/threads.tsx +++ b/src/cli/chatgpt-desktop/threads.tsx @@ -26,6 +26,7 @@ export const config = { type: 'string', }, limit: { default: 50, description: 'Max threads (1-200)', type: 'number' }, + cursor: { description: 'Opaque nextCursor from a previous page', type: 'string' }, modelProvider: { description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', @@ -42,6 +43,7 @@ export const inputSchema = z groupBy: z.literal('host').optional(), host: z.string().min(1).max(256).optional(), limit: z.number().int().min(1).max(200).default(50), + cursor: z.string().min(1).max(4096).optional(), modelProvider: z.string().min(1).max(256).optional(), port: z.number().int().min(1).max(65535).optional(), }) @@ -79,7 +81,7 @@ export default async function chatgptDesktopThreads({ provider ); }) - .join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` + .join('\n') + `\n\nbackend: ${String(out.backend ?? '')}` + (out.nextCursor ? `\nnextCursor: ${out.nextCursor}` : '') : resultText(out); return ( diff --git a/src/core/chatgpt-desktop/adapter.ts b/src/core/chatgpt-desktop/adapter.ts index aa8c625..c1d5453 100644 --- a/src/core/chatgpt-desktop/adapter.ts +++ b/src/core/chatgpt-desktop/adapter.ts @@ -18,6 +18,7 @@ export interface ChatGptDesktopAdapter { listTargets(): Promise; listThreads(options?: { limit?: number; + cursor?: string; /** Any string: `all` (default) | `local` | hostId / friendly name from list_hosts. Not an enum. */ host?: string; /** Any modelProvider id (app-server modelProviders). Omit = all. See list_hosts. Not an enum. */ diff --git a/src/core/chatgpt-desktop/app-server-fallback.ts b/src/core/chatgpt-desktop/app-server-fallback.ts index aa79273..f050ac0 100644 --- a/src/core/chatgpt-desktop/app-server-fallback.ts +++ b/src/core/chatgpt-desktop/app-server-fallback.ts @@ -64,14 +64,15 @@ export async function appServerSearchThreads({ } const matched: ChatGptDesktopThread[] = []; let cursor: string | undefined; - for (let page = 0; page < 20 && matched.length < limit; page++) { - const out = await listCodexThreads({ limit: 200, cursor, modelProviders }); + let exhausted = false; + for (let page = 0; page < 400 && matched.length < limit; page++) { + const out = await listCodexThreads({ limit: 25, cursor, modelProviders }); for (const thread of out.threads) { const mapped = mapListedThread(thread); if (threadMatchesQuery(mapped, needle)) matched.push(mapped); if (matched.length >= limit) break; } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + if (out.nextCursor == null || typeof out.nextCursor !== 'string') { exhausted = true; break; } cursor = out.nextCursor; } return { @@ -81,37 +82,45 @@ export async function appServerSearchThreads({ nextCursor: null, threads: matched.slice(0, limit), modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, + ...(!exhausted && matched.length < limit ? { warnings: ['Search stopped after 400 app-server pages; results may be incomplete'] } : {}), }; } export type ModelProvidersDiscovery = { readonly providers: readonly string[]; readonly source: 'thread/list-distinct'; + readonly threadCount?: number; + readonly complete?: boolean; }; /** Discover provider IDs from the supported inventory, without guessing RPCs. */ export async function discoverModelProviders(): Promise { const providers = new Set(); + let threadCount = 0; let cursor: string | undefined; - for (let page = 0; page < 20; page++) { - const out = await listCodexThreads({ limit: 200, cursor, modelProviders: [] }); + let complete = false; + for (let page = 0; page < 400; page++) { + const out = await listCodexThreads({ limit: 25, cursor, modelProviders: [] }); + threadCount += out.threads.length; for (const thread of out.threads) { if (typeof thread.modelProvider === 'string' && thread.modelProvider) { providers.add(thread.modelProvider); } } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') break; + if (out.nextCursor == null || typeof out.nextCursor !== 'string') { complete = true; break; } cursor = out.nextCursor; } return { providers: [...providers].sort(), source: 'thread/list-distinct', + threadCount, + complete, }; } export async function appServerReadThread({ threadId, - limit = 100, + limit, full = false, }: { threadId: string; @@ -119,6 +128,7 @@ export async function appServerReadThread({ full?: boolean; }): Promise { // Prefixed `local:` ids fail with `invalid thread id` — always strip first. + limit ??= full ? 2000 : 100; const bare = requireAppServerThreadId(threadId); // Known remote-only threads: fail fast with a typed error + host hint. @@ -149,13 +159,14 @@ async function readLocalThread( const { client } = await openCodexSession(); try { const meta = await readThreadMetadata(client, bare); - const turns = await listTurnsFull(client, bare, { limit, full }); + const { turns, complete } = await listTurnsFull(client, bare, { limit, full }); return { threadId: toDesktopThreadId(bare), turns, backend: 'app-server', limit, full, + complete, title: meta.title, cwd: meta.cwd, status: meta.status, @@ -297,18 +308,19 @@ async function listTurnsFull( client: AppServerClient, threadId: string, { limit, full }: { limit: number; full: boolean }, -): Promise { +): Promise<{ turns: ChatGptDesktopTurn[]; complete: boolean }> { const collected: unknown[] = []; let cursor: string | undefined; let itemsView = true; let method = 'thread/turns/list'; const seen = new Set(); + let complete = false; while (collected.length < limit) { let result: { data?: unknown[]; nextCursor?: string | null }; try { result = await client.request(method, { threadId, - limit: Math.min(100, limit - collected.length), + limit: Math.min(10, limit - collected.length), sortDirection: full ? 'asc' : 'desc', ...(method === 'thread/turns/list' && itemsView ? { itemsView: 'full' } : {}), ...(cursor !== undefined ? { cursor } : {}), @@ -327,7 +339,7 @@ async function listTurnsFull( } if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); collected.push(...result.data); - if (result.nextCursor == null) break; + if (result.nextCursor == null) { complete = true; break; } if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { throw new Error(`${method} returned an invalid or repeated cursor`); } @@ -335,7 +347,7 @@ async function listTurnsFull( cursor = result.nextCursor; } const turns = normalizeTurns(collected.slice(0, limit)); - return full ? turns : turns.reverse(); + return { turns: full ? turns : turns.reverse(), complete }; } function normalizeTurns(raw: unknown[]): ChatGptDesktopTurn[] { @@ -393,7 +405,7 @@ function normalizeTurnWithItems( ...(userText ? { userText } : {}), ...(assistantText ? { assistantText } : {}), startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, - endedAt: typeof row.endedAt === 'number' ? row.endedAt : null, + endedAt: typeof row.completedAt === 'number' ? row.completedAt : typeof row.endedAt === 'number' ? row.endedAt : null, }; } @@ -410,13 +422,17 @@ function normalizeLeafItem(id: string, row: Record): ChatGptDes role, text, startedAt: typeof row.startedAt === 'number' ? row.startedAt : null, - endedAt: typeof row.endedAt === 'number' ? row.endedAt : null, + endedAt: typeof row.completedAt === 'number' ? row.completedAt : typeof row.endedAt === 'number' ? row.endedAt : null, }; } function extractText(row: Record): string { if (typeof row.text === 'string') return row.text; if (typeof row.content === 'string') return row.content; + if (Array.isArray(row.content)) return row.content + .filter((part): part is Record => Boolean(part) && typeof part === 'object' && !Array.isArray(part)) + .map((part) => typeof part.text === 'string' ? part.text : '') + .filter(Boolean).join('\n'); if (typeof row.preview === 'string') return row.preview; return ''; } diff --git a/src/core/chatgpt-desktop/cdp-adapter.ts b/src/core/chatgpt-desktop/cdp-adapter.ts index a20ca32..ad26672 100644 --- a/src/core/chatgpt-desktop/cdp-adapter.ts +++ b/src/core/chatgpt-desktop/cdp-adapter.ts @@ -98,7 +98,7 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { full, threadId, }); - return { threadId, turns, backend: 'cdp', limit, full }; + return { threadId, turns, backend: 'cdp', limit, full, complete: false }; } async sendMessage({ diff --git a/src/core/chatgpt-desktop/cdp-dom.ts b/src/core/chatgpt-desktop/cdp-dom.ts index 9ed14d2..2894c0a 100644 --- a/src/core/chatgpt-desktop/cdp-dom.ts +++ b/src/core/chatgpt-desktop/cdp-dom.ts @@ -201,6 +201,7 @@ export const LIST_THREADS_EXPRESSION = `(() => { const project = projectFor(row); out.push({ threadId, + hostId: row.getAttribute('data-app-action-sidebar-thread-host-id') || null, title: row.getAttribute(${JSON.stringify(ATTR.threadTitle)}) || (row.textContent || '').trim(), pinned: row.getAttribute(${JSON.stringify(ATTR.threadPinned)}) === 'true', selected: row.getAttribute(${JSON.stringify(ATTR.threadSelected)}) === 'true', @@ -227,6 +228,28 @@ export function openThreadExpression(threadId: string): string { })()`; } +/** Desktop uses a memory router; the browser URL stays app://-/index.html. */ +export function navigateToThreadExpression(threadId: string): string { + const bare = durableThreadKey(threadId); + return `(async () => { + const root = window.__codexRoot?._internalRoot?.current; + const queue = [root]; + let scanned = 0; + while (queue.length && scanned++ < 10000) { + const fiber = queue.shift(); + if (!fiber) continue; + const router = fiber.memoizedProps?.router; + if (router?.navigate && router?.state?.location) { + await router.navigate(${JSON.stringify(`/local/${bare}`)}); + return { ok: true, via: 'router' }; + } + if (fiber.child) queue.push(fiber.child); + if (fiber.sibling) queue.push(fiber.sibling); + } + return { ok: false, error: 'router-not-found' }; + })()`; +} + export function startNewChatExpression(project?: string): string { const projectSel = project ? newChatInProjectSelector(project) : null; return `(() => { @@ -234,8 +257,11 @@ export function startNewChatExpression(project?: string): string { if (projectSel) { const preferred = document.querySelector(projectSel); if (preferred) { - preferred.click(); - return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)} }; + const row = preferred.closest('.group') || preferred.parentElement; + row?.scrollIntoView({ block: 'center' }); + const rowBox = row?.getBoundingClientRect(); + return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)}, + hoverX: rowBox?.left + rowBox?.width / 2, hoverY: rowBox?.top + rowBox?.height / 2 }; } return { ok: false, error: 'project-not-found' }; } @@ -247,6 +273,16 @@ export function startNewChatExpression(project?: string): string { })()`; } +export function projectButtonBoxExpression(project: string): string { + return `(() => { + const button = document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); + if (!button) return null; + const box = button.getBoundingClientRect(); + return { x: box.left + box.width / 2, y: box.top + box.height / 2, + visible: box.width > 0 && box.height > 0 && getComputedStyle(button.parentElement).opacity !== '0' }; + })()`; +} + export const LOADING_TASK_GONE_EXPRESSION = `(() => { const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); @@ -259,6 +295,10 @@ export const LOADING_TASK_GONE_EXPRESSION = `(() => { return !text.includes(${JSON.stringify(LOADING_TASK_TEXT)}); })()`; +export const ARCHIVED_THREAD_EXPRESSION = `(() => Array.from(document.querySelectorAll('main')) + .some((main) => (main.innerText || '').includes('This task is archived') + && (main.innerText || '').includes('Unarchive this task to open it')))()`; + export const FOCUS_COMPOSER_EXPRESSION = `(() => { const composer = document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); if (!composer) return { ok: false, error: 'composer-not-found' }; @@ -375,6 +415,7 @@ export async function listThreadsFromDom( pinned: Boolean(row.pinned), selected: Boolean(row.selected), kind: String(row.kind ?? 'unknown'), + ...(row.hostId ? { hostId: row.hostId, location: row.hostId === 'local' ? 'local' as const : 'remote' as const } : {}), ...(row.project ? { project: String(row.project) } : {}), })); } @@ -384,11 +425,21 @@ export async function openThreadInDom( sessionId: string, threadId: string, ): Promise { + const current = await readConversationIdFromDom(session, sessionId); + if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; + if (isTemporaryDesktopThreadId(threadId)) { + const rows = await listThreadsFromDom(session, sessionId, { limit: 200 }); + if (rows.some((row) => row.selected && row.threadId === threadId)) return; + } const result = await session.evaluate<{ ok: boolean; error?: string }>( openThreadExpression(threadId), { sessionId }, ); if (!result?.ok) { + if (result?.error === 'thread-not-found' && !isTemporaryDesktopThreadId(threadId)) { + const navigated = await session.evaluate<{ ok: boolean }>(navigateToThreadExpression(threadId), { sessionId }); + if (navigated?.ok) return; + } throw new Error( result?.error === 'thread-not-found' ? `ChatGPT Desktop thread not found: ${threadId}` @@ -403,11 +454,24 @@ export async function waitForLoadingTaskGone( { timeoutMs = DEFAULT_OPEN_TIMEOUT_MS, threadId }: { timeoutMs?: number; threadId?: string } = {}, ): Promise { const deadline = Date.now() + timeoutMs; + let loadingGone = false; + let lastConversationId = ''; + let archivedSince: number | null = null; while (Date.now() < deadline) { + if (threadId && threadId !== 'new' && await session.evaluate(ARCHIVED_THREAD_EXPRESSION, { sessionId }) === true) { + archivedSince ??= Date.now(); + if (Date.now() - archivedSince >= 500) { + throw new Error(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived; unarchive it in Desktop before opening`); + } + } else { + archivedSince = null; + } const gone = await session.evaluate(LOADING_TASK_GONE_EXPRESSION, { sessionId }); + loadingGone ||= gone; if (gone) { // A click can resolve before React replaces the previous timeline. const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; + lastConversationId = current; if (!threadId) return; if (threadId === 'new' || isTemporaryDesktopThreadId(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { limit: 200 }); @@ -418,7 +482,9 @@ export async function waitForLoadingTaskGone( await delay(250); } throw new Error( - `ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`, + loadingGone + ? `ChatGPT Desktop timed out waiting for conversation ${JSON.stringify(threadId)}; displayed conversation ${JSON.stringify(lastConversationId)} after ${timeoutMs}ms` + : `ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`, ); } @@ -427,7 +493,7 @@ export async function startNewChatInDom( sessionId: string, { project }: { project?: string } = {}, ): Promise<{ via: string }> { - const result = await session.evaluate<{ ok: boolean; via?: string; error?: string }>( + const result = await session.evaluate<{ ok: boolean; via?: string; error?: string; x?: number; y?: number; hoverX?: number; hoverY?: number }>( startNewChatExpression(project), { sessionId }, ); @@ -438,6 +504,19 @@ export async function startNewChatInDom( : 'ChatGPT Desktop "New chat" button not found', ); } + if (result.via === 'project') { + if (![result.hoverX, result.hoverY].every(Number.isFinite)) { + throw new Error(`ChatGPT Desktop project button has no visible box for ${JSON.stringify(project)}`); + } + await session.send('Input.dispatchMouseEvent', { type: 'mouseMoved', x: result.hoverX, y: result.hoverY }, { sessionId }); + const button = await session.evaluate<{ x: number; y: number; visible: boolean } | null>(projectButtonBoxExpression(project!), { sessionId }); + if (!button?.visible || !Number.isFinite(button.x) || !Number.isFinite(button.y)) { + throw new Error(`ChatGPT Desktop project button did not appear after hover for ${JSON.stringify(project)}`); + } + await session.send('Input.dispatchMouseEvent', { type: 'mouseMoved', x: button.x, y: button.y }, { sessionId }); + await session.send('Input.dispatchMouseEvent', { type: 'mousePressed', x: button.x, y: button.y, button: 'left', clickCount: 1 }, { sessionId }); + await session.send('Input.dispatchMouseEvent', { type: 'mouseReleased', x: button.x, y: button.y, button: 'left', clickCount: 1 }, { sessionId }); + } return { via: result.via ?? 'unknown' }; } @@ -672,15 +751,19 @@ export async function readTurnsFromDom( } = {}, ): Promise { const collected = new Map(); + const order: string[] = []; const ingest = async () => { + const older: string[] = []; for (const turn of await harvestVisibleTurns(session, sessionId)) { + if (!collected.has(turn.turnKey)) older.push(turn.turnKey); collected.set(turn.turnKey, turn); } + order.unshift(...older); }; await ingest(); if (!full) { - const visible = [...collected.values()]; + const visible = order.map((key) => collected.get(key)!); return limit > 0 ? visible.slice(-limit) : visible; } @@ -717,7 +800,7 @@ export async function readTurnsFromDom( if (threadId && collected.has(threadId)) break; } - const all = [...collected.values()]; + const all = order.map((key) => collected.get(key)!); return limit > 0 ? all.slice(0, limit) : all; } diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index 4d2f559..5958051 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -49,8 +49,12 @@ const defaultFallbacks: ChatGptDesktopFallbacks = { discoverModelProviders, }; +const REMOTE_PAGE_CURSOR = 'desktop-remote-page:'; +const APP_START_CURSOR = 'desktop-app-start'; + export type ListThreadsOptions = { limit?: number; + cursor?: string; /** * Any string (not an enum). Reserved: `all` (default), `local`. Otherwise a * hostId or friendly name discovered at runtime — see `listHosts` / @@ -111,19 +115,20 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { const limit = options.limit ?? 50; const host = normalizeHostFilter(options.host); const modelProviders = modelProvidersFromFilter(options.modelProvider); - let appList: ListThreadsResult | null = null; - let appError: unknown; - try { - appList = await this.#fallbacks.listThreads({ limit, modelProviders }); - } catch (error) { - appError = error; + const remoteOffset = options.cursor?.startsWith(REMOTE_PAGE_CURSOR) + ? Number(options.cursor.slice(REMOTE_PAGE_CURSOR.length)) : null; + if (remoteOffset !== null && (!Number.isSafeInteger(remoteOffset) || remoteOffset < 1)) { + throw new Error('Invalid ChatGPT Desktop remote page cursor'); } - + const inventoryPage = !options.cursor || remoteOffset !== null; + const remotes = inventoryPage ? this.#listRemotes() : []; let cdpList: ListThreadsResult | null = null; let cdpError: unknown; try { - await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads({ limit }); + if (inventoryPage) { + await this.#ensureCdp(); + cdpList = await this.#cdp.listThreads({ limit: 200 }); + } } catch (error) { if (isCdpFailure(error)) { this.#cdpConnected = false; @@ -132,30 +137,66 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { } } - const remotes = this.#listRemotes(); + if (inventoryPage && host !== 'local') { + const remoteInventory = finalizeThreadList({ + backend: cdpList?.backend ?? 'remote-state', limit: 10_000, + threads: cdpList?.threads.filter((thread) => thread.location === 'remote') ?? [], + }, { limit: 10_000, host, modelProvider: options.modelProvider, remotes }); + const offset = remoteOffset ?? 0; + if (remoteOffset !== null || remoteInventory.threads.length >= limit) { + const page = remoteInventory.threads.slice(offset, offset + limit); + const nextOffset = offset + page.length; + const nextCursor = nextOffset < remoteInventory.threads.length + ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; + return { ...remoteInventory, threads: page, limit, nextCursor, + ...(options.groupBy === 'host' ? { groupBy: 'host', groups: groupThreadsByHost(page) } : {}) }; + } + } + + const remoteKeys = new Set(remotes.map((thread) => toAppServerThreadId(thread.threadId) ?? thread.threadId)); + const reservedRemoteRows = host === 'all' && inventoryPage + ? remotes.filter((thread) => modelProviderMatches(thread, options.modelProvider)).length + + (cdpList?.threads.filter((thread) => thread.location === 'remote' + && modelProviderMatches(thread, options.modelProvider) + && !remoteKeys.has(toAppServerThreadId(thread.threadId) ?? thread.threadId)).length ?? 0) + : 0; + const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); + let appList: ListThreadsResult | null = null; + let appError: unknown; + try { + appList = await this.#fallbacks.listThreads({ limit: appLimit, + cursor: options.cursor === APP_START_CURSOR ? undefined : options.cursor, modelProviders }); + } catch (error) { + appError = error; + } + let base: ListThreadsResult | null = null; if (appList && cdpList) base = mergeThreadLists(appList, cdpList); else if (appList) base = appList; else if (cdpList) base = cdpList; - else if (remotes.length) base = { backend: 'app-server', limit, threads: [] }; + else if (remotes.length) base = { backend: 'remote-state', limit, threads: [] }; else if (cdpError) throw cdpError; else if (appError) throw appError; else throw new CdpUnreachableError('ChatGPT Desktop listThreads: CDP and app-server unreachable'); - return finalizeThreadList(base, { + const result = finalizeThreadList(base, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes, }); + const withCursor = host === 'all' || host === 'local' ? result : { ...result, nextCursor: null }; + return appError ? { ...withCursor, warnings: [`App-server list failed: ${appError instanceof Error ? appError.message : String(appError)}`] } : withCursor; } async listHosts(): Promise { const remotes = this.#listRemotes(); + const cdpRows = typeof this.#cdp.listThreads === 'function' + ? (await this.#tryCdpList({ limit: 200 }))?.threads ?? [] : []; let localThreadCount = 0; try { - const local = await this.#fallbacks.listThreads({ limit: 200, modelProviders: [] }); + const local = await this.#fallbacks.listThreads({ limit: 25, modelProviders: [] }); localThreadCount = local.threads.length; } catch { localThreadCount = 0; @@ -183,13 +224,29 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { } } - const hostsSource = 'remote-thread-summaries-v3+local'; + for (const thread of cdpRows) { + if (thread.location !== 'remote' || !thread.hostId) continue; + if (!byId.has(thread.hostId)) byId.set(thread.hostId, { + hostId: thread.hostId, hostName: thread.hostName ?? null, location: 'remote', threadCount: 0, + }); + } + + const hostsSource = 'local+remote-thread-summaries-v3+managed-connections' + + (cdpRows.length ? '+cdp' : ''); // Recount remotes from the parsed summary rows for accuracy. const remoteCounts = new Map(); for (const thread of remotes) { remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); } + const remoteIds = new Set(remotes.map((thread) => toAppServerThreadId(thread.threadId) ?? thread.threadId)); + for (const thread of cdpRows) { + if (thread.location !== 'remote' || !thread.hostId) continue; + const id = toAppServerThreadId(thread.threadId) ?? thread.threadId; + if (remoteIds.has(id)) continue; + remoteIds.add(id); + remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + } const withCounts = [...byId.values()] .map((host) => host.hostId === 'local' @@ -204,12 +261,16 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { let modelProviders: string[] = []; let modelProvidersSource = 'thread/list-distinct'; + const warnings: string[] = []; try { const discover = this.#fallbacks.discoverModelProviders ?? discoverModelProviders; const discovered = await discover(); modelProviders = [...discovered.providers]; modelProvidersSource = discovered.source; - } catch { + if (typeof discovered.threadCount === 'number') localThreadCount = discovered.threadCount; + if (discovered.complete === false) warnings.push('Provider discovery stopped before the final app-server page'); + } catch (error) { + warnings.push(`Model provider discovery failed: ${error instanceof Error ? error.message : String(error)}`); modelProviders = [...new Set( remotes .map((thread) => thread.modelProvider) @@ -222,11 +283,14 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { ...remotes.map((thread) => thread.modelProvider).filter((value): value is string => Boolean(value)), ])].sort(); return { - hosts: withCounts, + hosts: withCounts.map((host) => host.hostId === 'local' ? { ...host, threadCount: localThreadCount } : host), hostsSource, modelProviders, modelProvidersSource, - backend: 'app-server', + backend: cdpRows.length + ? (remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp') + : (remotes.length ? 'app-server+remote-state' : 'app-server'), + ...(warnings.length ? { warnings } : {}), }; } @@ -260,13 +324,14 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { query: options.query, threads: withRemotes.threads.filter((thread) => threadMatchesQuery(thread, needle)), }; - return finalizeThreadList(filtered, { + const result = finalizeThreadList(filtered, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: [], }); + return result; } catch (appError) { const cdpList = await this.#tryCdpList({ limit }); const remotes = this.#listRemotes(); @@ -277,13 +342,14 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { query: options.query, threads: (cdpList?.threads ?? []).filter((thread) => threadMatchesQuery(thread, needle)), }; - return finalizeThreadList(filtered, { + const result = finalizeThreadList(filtered, { limit, host, modelProvider: options.modelProvider?.trim() || undefined, groupBy: options.groupBy, remotes: remotes.filter((thread) => threadMatchesQuery(thread, needle)), }); + return { ...result, warnings: [`App-server search failed: ${appError instanceof Error ? appError.message : String(appError)}`] }; } } @@ -293,7 +359,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { full?: boolean; openTimeoutMs?: number; }): Promise { - const limit = options.limit ?? 100; + const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; if (isTemporaryDesktopThreadId(options.threadId)) { @@ -311,7 +377,8 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { if (appError instanceof RemoteThreadNotLoadedError) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; - return this.#cdp.readThread({ ...options, limit, full }); + const fallback = await this.#cdp.readThread({ ...options, limit, full }); + return { ...fallback, complete: false, warnings: [`App-server read failed: ${appError instanceof Error ? appError.message : String(appError)}`] }; } } @@ -349,7 +416,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { } catch { appServerFallback = { reachable: false }; } - const reachable = cdpStatus.reachable || Boolean(appServerFallback?.reachable); + const reachable = cdpStatus.reachable; return { ...cdpStatus, port: this.#port, @@ -357,9 +424,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { reachable, message: cdpStatus.reachable ? cdpStatus.message - : appServerFallback?.reachable - ? 'CDP unreachable; Codex app-server available for list/search/read' - : cdpStatus.message, + : cdpStatus.message, exitCode: reachable ? 0 : 1, }; } @@ -437,6 +502,9 @@ export function mergeThreadLists( selected: cdp.selected, kind: cdp.kind || withLocal.kind, project: cdp.project ?? withLocal.project, + location: cdp.location === 'remote' ? 'remote' : withLocal.location, + hostId: cdp.location === 'remote' ? cdp.hostId ?? null : withLocal.hostId, + hostName: cdp.location === 'remote' ? cdp.hostName ?? null : withLocal.hostName, }; }); @@ -446,7 +514,7 @@ export function mergeThreadLists( } return { - backend: appList.backend, + backend: 'app-server+cdp', limit: appList.limit, nextCursor: appList.nextCursor, ...(appList.query !== undefined ? { query: appList.query } : {}), @@ -476,7 +544,7 @@ export function finalizeThreadList( ])); const locals = base.threads.map((thread) => { const remote = remoteById.get(toAppServerThreadId(thread.threadId) ?? thread.threadId); - if (remote && thread.location === undefined) { + if (remote) { return { ...thread, ...remote, selected: thread.selected, pinned: thread.pinned || remote.pinned }; } const location = thread.location ?? ('local' as const); @@ -502,6 +570,7 @@ export function finalizeThreadList( hostName: remote.hostName ?? null, }); } + if (remotes.length) merged.sort((a, b) => Number(b.location === 'remote') - Number(a.location === 'remote')); const filtered = merged.filter((thread) => { if (!hostMatches(thread, host)) return false; @@ -510,7 +579,11 @@ export function finalizeThreadList( }); const limited = filtered.slice(0, limit); const result: ListThreadsResult = { - backend: base.backend, + backend: remotes.length + ? (base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' + : base.backend === 'app-server' ? 'app-server+remote-state' + : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend) + : base.backend, limit, threads: limited, ...(base.nextCursor !== undefined ? { nextCursor: base.nextCursor } : {}), diff --git a/src/core/chatgpt-desktop/remote-threads.ts b/src/core/chatgpt-desktop/remote-threads.ts index 2e7676e..5022ecb 100644 --- a/src/core/chatgpt-desktop/remote-threads.ts +++ b/src/core/chatgpt-desktop/remote-threads.ts @@ -9,7 +9,7 @@ * SSH remoting is intentionally not implemented here (follow-up). */ -import { loadCodexGlobalState } from '../codex/remote-control.js'; +import { codexStateEntries, loadCodexGlobalState } from '../codex/remote-control.js'; export { codexGlobalStatePath, loadCodexGlobalState } from '../codex/remote-control.js'; import { toAppServerThreadId, toDesktopThreadId } from './thread-ids.js'; @@ -47,7 +47,7 @@ export function listRemoteThreadsFromState( const out: RemoteThreadRecord[] = []; const seen = new Set(); - for (const [key, value] of Object.entries(data)) { + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)) { const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; @@ -121,12 +121,12 @@ export function listDiscoveredHosts( const data = loadCodexGlobalState(env); if (data) { const hostNames = collectHostNames(data); - for (const key of Object.keys(data)) { + for (const [key, summary] of codexStateEntries(data).flatMap(Object.entries)) { const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; - const summary = data[key]; const hostName = hostNames.get(hostId) ?? extractHostName(summary) ?? null; + if (byHost.has(hostId)) continue; byHost.set(hostId, { hostId, hostName, @@ -134,6 +134,14 @@ export function listDiscoveredHosts( threadCount: 0, }); } + const connections = data['codex-managed-remote-connections']; + if (Array.isArray(connections)) for (const entry of connections) { + if (!entry || typeof entry !== 'object' || Array.isArray(entry)) continue; + const hostId = stringField(entry, ['hostId']); + if (hostId && !byHost.has(hostId)) byHost.set(hostId, { + hostId, hostName: stringField(entry, ['displayName', 'alias']), location: 'remote', threadCount: 0, + }); + } } for (const thread of remotes) { @@ -163,24 +171,29 @@ export function listDiscoveredHosts( function collectHostNames(data: Record): Map { const names = new Map(); - for (const [key, value] of Object.entries(data)) { + const connections = data['codex-managed-remote-connections']; + if (Array.isArray(connections)) for (const entry of connections) { + const pair = hostNameFromEntry(entry); + if (pair) names.set(pair.hostId, pair.hostName); + } + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)) { if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; if (!value || typeof value !== 'object') continue; if (Array.isArray(value)) { for (const entry of value) { const pair = hostNameFromEntry(entry); - if (pair) names.set(pair.hostId, pair.hostName); + if (pair && !names.has(pair.hostId)) names.set(pair.hostId, pair.hostName); } continue; } for (const [hostId, entry] of Object.entries(value as Record)) { const fromEntry = hostNameFromEntry(entry); if (fromEntry) { - names.set(fromEntry.hostId, fromEntry.hostName); + if (!names.has(fromEntry.hostId)) names.set(fromEntry.hostId, fromEntry.hostName); continue; } const label = stringField(entry, ['name', 'hostName', 'displayName', 'envName', 'label', 'title']); - if (label) names.set(hostId, label); + if (label && !names.has(hostId)) names.set(hostId, label); } } return names; diff --git a/src/core/chatgpt-desktop/routes.ts b/src/core/chatgpt-desktop/routes.ts index 801082e..5be1fdf 100644 --- a/src/core/chatgpt-desktop/routes.ts +++ b/src/core/chatgpt-desktop/routes.ts @@ -17,6 +17,7 @@ export const listThreadsSchema = z .object({ port: z.number().int().min(1).max(65535).optional(), limit: z.number().int().min(1).max(200).default(50), + cursor: z.string().min(1).max(4096).optional(), /** * Any string. Reserved: `all` (default), `local`. Otherwise a hostId or * friendly name discovered at runtime — see `chatgpt_desktop_list_hosts`. @@ -56,7 +57,7 @@ export const readThreadSchema = z .object({ port: z.number().int().min(1).max(65535).optional(), threadId, - limit: z.number().int().min(1).max(2000).default(100), + limit: z.number().int().min(1).max(2000).optional(), full: z.boolean().default(false), openTimeoutMs: z.number().int().min(1).max(600_000).default(90_000), }) @@ -165,6 +166,7 @@ export async function listThreadsOperation( const out = await withAdapter(input.port, (adapter) => adapter.listThreads({ limit: input.limit, + cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, groupBy: input.groupBy, @@ -221,7 +223,7 @@ export async function readThreadOperation( const out = await withAdapter(input.port, (adapter) => adapter.readThread({ threadId: input.threadId, - limit: input.limit, + limit: input.limit ?? (input.full ? 2000 : 100), full: input.full, openTimeoutMs: input.openTimeoutMs, }), diff --git a/src/core/chatgpt-desktop/types.ts b/src/core/chatgpt-desktop/types.ts index 19f8f1c..383e171 100644 --- a/src/core/chatgpt-desktop/types.ts +++ b/src/core/chatgpt-desktop/types.ts @@ -1,4 +1,4 @@ -export type ChatGptDesktopBackend = 'cdp' | 'app-server'; +export type ChatGptDesktopBackend = 'cdp' | 'app-server' | 'app-server+cdp' | 'app-server+remote-state' | 'app-server+cdp+remote-state' | 'cdp+remote-state' | 'remote-state'; export type ChatGptDesktopTarget = { readonly targetId: string; @@ -85,6 +85,7 @@ export type ListThreadsResult = { readonly backend: ChatGptDesktopBackend; readonly limit: number; readonly nextCursor?: string | null; + readonly warnings?: readonly string[]; readonly query?: string; /** Host filter applied: any string (`all` | `local` | hostId / friendly name from list_hosts). */ readonly host?: string; @@ -108,6 +109,7 @@ export type ListHostsResult = { /** How model providers were discovered (app-server method or thread/list-distinct). */ readonly modelProvidersSource: string; readonly backend: ChatGptDesktopBackend; + readonly warnings?: readonly string[]; }; export type ReadThreadResult = { @@ -116,6 +118,8 @@ export type ReadThreadResult = { readonly backend: ChatGptDesktopBackend; readonly limit: number; readonly full: boolean; + readonly complete?: boolean; + readonly warnings?: readonly string[]; readonly title?: string; readonly cwd?: string | null; readonly status?: string; diff --git a/src/core/codex-bridge.js b/src/core/codex-bridge.js index a6c8e28..0c6e5ac 100644 --- a/src/core/codex-bridge.js +++ b/src/core/codex-bridge.js @@ -29,8 +29,9 @@ const WS_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // Transport budgets: fail fast instead of buffering unbounded attacker-controlled bytes. // ponytail: raise these only with streaming/pagination support; the app-server sends small JSON-RPC frames. const WS_MAX_HEADER_BYTES = 16 * 1024; -const WS_MAX_MESSAGE_BYTES = 4 * 1024 * 1024; -const WS_MAX_BUFFER_BYTES = 8 * 1024 * 1024; +const WS_MAX_MESSAGE_BYTES = 16 * 1024 * 1024; +const WS_MAX_BUFFER_BYTES = 32 * 1024 * 1024; +const CODEX_SEND_MAX_BYTES = 4 * 1024 * 1024; export const WS_MAX_WRITE_BYTES = 8 * 1024 * 1024; export const CODEX_MAX_REQUESTS = 128; export const CODEX_MAX_LISTENERS = 128; @@ -1181,7 +1182,7 @@ async function sendToCodexThreadInner(threadId, text, { env, envelope, whenBusy, if (!["reject", "queue", ...(session ? ["steer"] : [])].includes(whenBusy)) throw new RangeError("--when-busy must be reject, queue, or persistent steer"); if (whenBusy === "steer" && (typeof expectedTurnId !== "string" || !ID_PATTERN.test(expectedTurnId))) throw new RangeError("steer requires expectedTurnId"); threadId = normalizeCodexThreadId(threadId); - if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > WS_MAX_MESSAGE_BYTES) throw new RangeError("Message must contain text within 4 MiB"); + if (typeof text !== "string" || !text.trim() || Buffer.byteLength(text) > CODEX_SEND_MAX_BYTES) throw new RangeError("Message must contain text within 4 MiB"); if (!envelope || typeof envelope.messageId !== "string" || !ID_PATTERN.test(envelope.messageId)) throw new RangeError("Invalid envelope messageId"); const validated = buildEnvelope({ correlationId: envelope.correlationId, replyTo: envelope.replyTo, hop: envelope.hop, env }); envelope = { ...validated, messageId: envelope.messageId, header: Boolean(envelope.header) }; diff --git a/src/core/codex/remote-control.js b/src/core/codex/remote-control.js index a68799d..2ccabbe 100644 --- a/src/core/codex/remote-control.js +++ b/src/core/codex/remote-control.js @@ -74,6 +74,12 @@ export function loadCodexGlobalState(env = process.env) { } } +/** Desktop keeps atom keys one level below the global state root. */ +export function codexStateEntries(data) { + const nested = data?.['electron-persisted-atom-state']; + return [nested, data].filter((value) => value && typeof value === 'object' && !Array.isArray(value)); +} + /** * @param {string} threadId * @param {NodeJS.ProcessEnv} [env] @@ -93,7 +99,7 @@ export function findRemoteThreadHost(threadId, env = process.env) { if (!data) return null; const hostNames = collectHostNames(data); - for (const [key, value] of Object.entries(data)) { + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)) { const match = REMOTE_SUMMARY_KEY.exec(key); if (!match?.[1]) continue; const hostId = match[1]; @@ -136,24 +142,24 @@ export function mapRemoteThreadError(error, threadId, env = process.env) { function collectHostNames(data) { const names = new Map(); - for (const [key, value] of Object.entries(data)) { + for (const [key, value] of codexStateEntries(data).flatMap(Object.entries)) { if (!/remote-host|hosts|host-meta|host_directory|environments/i.test(key)) continue; if (!value || typeof value !== 'object') continue; if (Array.isArray(value)) { for (const entry of value) { const pair = hostNameFromEntry(entry); - if (pair) names.set(pair.hostId, pair.hostName); + if (pair && !names.has(pair.hostId)) names.set(pair.hostId, pair.hostName); } continue; } for (const [hostId, entry] of Object.entries(value)) { const fromEntry = hostNameFromEntry(entry); if (fromEntry) { - names.set(fromEntry.hostId, fromEntry.hostName); + if (!names.has(fromEntry.hostId)) names.set(fromEntry.hostId, fromEntry.hostName); continue; } const label = stringField(entry, ['name', 'hostName', 'displayName', 'envName', 'label', 'title']); - if (label) names.set(hostId, label); + if (label && !names.has(hostId)) names.set(hostId, label); } } return names; diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx index c02180a..5ce90cc 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list hosts', description: - 'Discover ChatGPT Desktop hosts and modelProviders at runtime. Hosts come from local and remote-thread-summaries-v3: metadata; providers are distinct thread/list and remote-summary values. New connections appear without code changes. Result includes hostsSource and modelProvidersSource', + 'Discover local, remote-control, and managed SSH hosts from Desktop state, including nested remote-thread summaries. Host names are null when Desktop has no display name. Providers come from paged app-server inventory and remote summaries. Result includes sources and discovery warnings.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx index d8c7d9a..4f3e571 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list threads', description: - 'List ChatGPT Desktop / Codex threads: local app-server thread/list merged with remote-control summaries from ~/.codex/.codex-global-state.json. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Each thread has location local|remote and hostId/hostName. Result includes backend.', + 'Page ChatGPT Desktop / Codex threads with cursor and nextCursor. Merges local app-server rows, CDP sidebar rows, and nested remote-control summaries. Discover dynamic host and modelProvider filters via chatgpt_desktop_list_hosts. Optional groupBy=host. Result reports the contributing backends and warnings.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -23,6 +23,7 @@ export default defineTool( properties: { port: { type: 'number' }, limit: { type: 'number', description: 'Maximum threads (1-200).' }, + cursor: { type: 'string', description: 'Opaque nextCursor from a previous page.' }, host: { type: 'string', description: diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx index 40578dd..3636958 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop read thread', description: - 'Read a ChatGPT Desktop / Codex thread through app-server (thread/read metadata, then thread/turns/list with itemsView full). Does not thread/resume. Desktop local: is normalized to the bare id. Remote-control threads return REMOTE_THREAD_NOT_LOADED with hostId and a hint to read via that host\'s app-server. DOM harvest is fallback only when local app-server is unavailable. Result includes backend.', + 'Read paged ChatGPT Desktop turns through app-server, including userText, assistantText, and completedAt as endedAt. Remote-only threads return REMOTE_THREAD_NOT_LOADED with hostId. CDP fallback reports complete:false and a warning when app-server fails. Result includes backend.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -32,7 +32,7 @@ export default defineTool( full: { type: 'boolean', description: - 'When true, page more of the turn history from the start; otherwise return the most recent `limit` turns from app-server. CDP wheel only if app-server is unavailable.', + 'When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.', }, openTimeoutMs: { type: 'number', diff --git a/test/codex-bridge.test.js b/test/codex-bridge.test.js index 4fa1209..9c8afcc 100644 --- a/test/codex-bridge.test.js +++ b/test/codex-bridge.test.js @@ -676,7 +676,7 @@ test("codex status rejects a complete oversized frame without buffering it", asy ...baseHandlers, initialize: (params, ok, err, send, socket) => { void params; void ok; void err; void send; - socket.write(encodeFrame(0x1, Buffer.alloc(5 * 1024 * 1024))); + socket.write(encodeFrame(0x1, Buffer.alloc(17 * 1024 * 1024))); }, }); try { diff --git a/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts b/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts new file mode 100644 index 0000000..4cecaa8 --- /dev/null +++ b/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts @@ -0,0 +1,255 @@ +import { mkdtempSync, writeFileSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { afterEach, expect, it, rstest } from '@rstest/core'; +import { findRemoteThreadHost } from '../../src/core/codex/remote-control.js'; +import { listDiscoveredHosts, listRemoteThreadsFromState } from '../../src/core/chatgpt-desktop/remote-threads.js'; +import { ChatGptDesktopFacade, finalizeThreadList } from '../../src/core/chatgpt-desktop/facade.js'; +import { appServerReadThread, appServerSearchThreads, discoverModelProviders } from '../../src/core/chatgpt-desktop/app-server-fallback.js'; +import { ARCHIVED_THREAD_EXPRESSION, CONVERSATION_ID_EXPRESSION, LOADING_TASK_GONE_EXPRESSION, navigateToThreadExpression, openThreadInDom, readTurnsFromDom, startNewChatExpression, startNewChatInDom, waitForLoadingTaskGone } from '../../src/core/chatgpt-desktop/cdp-dom.js'; +import { listThreadsOperation, listThreadsSchema, readThreadOperation, readThreadSchema, statusOperation } from '../../src/core/chatgpt-desktop/routes.js'; +import { setChatGptDesktopAdapterForTests } from '../../src/core/chatgpt-desktop/facade.js'; +import type { ChatGptDesktopAdapter } from '../../src/core/chatgpt-desktop/adapter.js'; + +afterEach(() => { rstest.restoreAllMocks(); setChatGptDesktopAdapterForTests(null); }); + +it('reads nested remote summaries and SSH connections without inventing a display name', () => { + const home = mkdtempSync(join(tmpdir(), 'gbot-remote-state-')); + try { + writeFileSync(join(home, '.codex-global-state.json'), JSON.stringify({ + 'electron-persisted-atom-state': { + 'remote-thread-summaries-v3:remote-control:env_dynamic': [ + { conversationId: 'remote-thread', hostId: 'remote-control:env_dynamic', title: 'TD v2', modelProvider: 'openai' }, + ], + }, + 'codex-managed-remote-connections': [{ hostId: 'ssh:dynamic', displayName: 'ssh-box' }], + })); + const env = { CODEX_HOME: home }; + expect(listRemoteThreadsFromState(env)[0]).toMatchObject({ threadId: 'local:remote-thread', hostId: 'remote-control:env_dynamic', hostName: null }); + expect(findRemoteThreadHost('local:remote-thread', env)).toEqual({ hostId: 'remote-control:env_dynamic', hostName: null }); + expect(listDiscoveredHosts(env)).toEqual(expect.arrayContaining([ + expect.objectContaining({ hostId: 'remote-control:env_dynamic', hostName: null, threadCount: 1 }), + expect.objectContaining({ hostId: 'ssh:dynamic', hostName: 'ssh-box' }), + ])); + } finally { rmSync(home, { recursive: true, force: true }); } +}); + +it('joins a CDP row to remote ownership and reports mixed backends', () => { + const row = { threadId: 'local:remote-thread', title: 'TD v2', pinned: false, selected: true, kind: 'remote' }; + const out = finalizeThreadList({ backend: 'app-server+cdp', limit: 20, threads: [row] }, { + limit: 20, host: 'env_dynamic', remotes: [{ ...row, selected: false, location: 'remote', hostId: 'remote-control:env_dynamic', hostName: null }], + }); + expect(out).toMatchObject({ backend: 'app-server+cdp+remote-state', threads: [{ location: 'remote', hostId: 'remote-control:env_dynamic', selected: true }] }); +}); + +it('counts CDP-only remote rows in host discovery', async () => { + const row = { threadId: 'local:cdp-only', title: 'remote', pinned: false, selected: false, kind: 'remote', location: 'remote' as const, hostId: 'remote:dynamic', hostName: null }; + const facade = new ChatGptDesktopFacade({ + connect: async () => {}, listThreads: async () => ({ backend: 'cdp', limit: 200, threads: [row] }), + } as unknown as ChatGptDesktopAdapter, 9222, { + listThreads: async () => ({ backend: 'app-server', limit: 25, threads: [] }), + listRemoteThreads: () => [], listHosts: () => [{ hostId: 'local', hostName: 'local', location: 'local', threadCount: 0 }], + discoverModelProviders: async () => ({ providers: [], source: 'thread/list-distinct', threadCount: 0, complete: true }), + } as never); + expect((await facade.listHosts()).hosts).toEqual(expect.arrayContaining([expect.objectContaining({ hostId: 'remote:dynamic', threadCount: 1 })])); +}); + +it('surfaces provider discovery errors with the remote fallback', async () => { + const facade = new ChatGptDesktopFacade({} as ChatGptDesktopAdapter, 9222, { + listThreads: async () => ({ backend: 'app-server', limit: 25, threads: [] }), + listRemoteThreads: () => [], listHosts: () => [], + discoverModelProviders: async () => { throw new Error('frame too large'); }, + } as never); + expect((await facade.listHosts()).warnings).toEqual(['Model provider discovery failed: frame too large']); +}); + +it('uses small app-server pages for provider discovery and search', async () => { + const bridge = await import('../../src/core/codex-bridge.js'); + const limits: number[] = []; + rstest.spyOn(bridge, 'listCodexThreads').mockImplementation(async ({ limit, cursor } = {}) => { + limits.push(limit!); + return { limit: limit!, nextCursor: cursor ? null : 'more', threads: [{ id: cursor ? 'b' : 'a', name: cursor ? 'needle' : 'first', modelProvider: cursor ? 'second-provider' : 'first-provider' }] } as never; + }); + expect((await discoverModelProviders()).providers).toEqual(['first-provider', 'second-provider']); + expect((await appServerSearchThreads({ query: 'needle' })).threads).toHaveLength(1); + expect(limits).toEqual([25, 25, 25, 25]); +}); + +it('pages full turn reads, extracts user content and completedAt, and keeps stable keys', async () => { + const bridge = await import('../../src/core/codex-bridge.js'); + const limits: number[] = []; + rstest.spyOn(bridge, 'openCodexSession').mockResolvedValue({ client: { + close() {}, + async request(method: string, params: Record) { + if (method === 'thread/read') return { thread: { id: 'long-thread' } }; + limits.push(params.limit as number); + const id = params.cursor ? 'second' : 'first'; + return { data: [{ id, startedAt: 10, completedAt: 20, items: [ + { type: 'userMessage', content: [{ type: 'text', text: `ask ${id}` }] }, + { type: 'agentMessage', text: `answer ${id}` }, + ] }], nextCursor: params.cursor ? null : 'more' }; + }, + } } as never); + const out = await appServerReadThread({ threadId: 'long-thread', full: true, limit: 20 }); + expect(out.complete).toBe(true); + expect(out.turns).toMatchObject([ + { turnKey: 'history-content:turn:first', userText: 'ask first', assistantText: 'answer first', endedAt: 20 }, + { turnKey: 'history-content:turn:second', userText: 'ask second', endedAt: 20 }, + ]); + expect(limits).toEqual([10, 10]); +}); + +it('completes a 146-turn full read in bounded pages', async () => { + const bridge = await import('../../src/core/codex-bridge.js'); + const pages: number[] = []; + rstest.spyOn(bridge, 'openCodexSession').mockResolvedValue({ client: { + close() {}, + async request(method: string, params: Record) { + if (method === 'thread/read') return { thread: { id: 'long-thread' } }; + const offset = Number(params.cursor ?? 0); + const size = Math.min(params.limit as number, 146 - offset); + pages.push(params.limit as number); + return { data: Array.from({ length: size }, (_, i) => ({ id: `turn-${offset + i}`, items: [] })), + nextCursor: offset + size < 146 ? String(offset + size) : null }; + }, + } } as never); + const out = await appServerReadThread({ threadId: 'long-thread', full: true, limit: 200 }); + expect(out.turns).toHaveLength(146); + expect(out.complete).toBe(true); + expect(pages).toHaveLength(15); + expect(Math.max(...pages)).toBe(10); +}); + +it('defaults full reads to the bounded complete-history limit', async () => { + const limits: number[] = []; + setChatGptDesktopAdapterForTests({ + connect: async () => {}, close: async () => {}, + readThread: async (options: { threadId: string; limit?: number; full?: boolean }) => { + limits.push(options.limit!); + return { threadId: options.threadId, turns: [], backend: 'app-server', limit: options.limit!, full: Boolean(options.full), complete: true }; + }, + } as unknown as ChatGptDesktopAdapter); + await readThreadOperation(readThreadSchema.parse({ threadId: 'example', full: true })); + await readThreadOperation(readThreadSchema.parse({ threadId: 'example' })); + expect(limits).toEqual([2000, 100]); +}); + +it('marks a CDP read partial and preserves the app-server failure', async () => { + const facade = new ChatGptDesktopFacade({ + connect: async () => {}, + readThread: async () => ({ threadId: 'local:example', turns: [], backend: 'cdp', limit: 100, full: true }), + } as unknown as ChatGptDesktopAdapter, 9222, { + readThread: async () => { throw new Error('frame exceeds 16 MiB'); }, + } as never); + expect(await facade.readThread({ threadId: 'local:example', full: true })).toMatchObject({ + backend: 'cdp', complete: false, warnings: ['App-server read failed: frame exceeds 16 MiB'], + }); +}); + +it('passes the opaque list cursor through facade and route', async () => { + const calls: unknown[] = []; + const facade = new ChatGptDesktopFacade({ connect: async () => { throw new Error('offline'); } } as unknown as ChatGptDesktopAdapter, 9222, { + listThreads: async (options: { cursor?: string; limit?: number }) => { calls.push(options.cursor); return { backend: 'app-server', limit: options.limit ?? 50, nextCursor: 'next-page', threads: [] }; }, + listRemoteThreads: () => [], + } as never); + expect((await facade.listThreads({ cursor: 'previous' })).nextCursor).toBe('next-page'); + expect(calls).toEqual(['previous']); + expect(listThreadsSchema.parse({ cursor: 'previous' }).cursor).toBe('previous'); + setChatGptDesktopAdapterForTests({ connect: async () => {}, close: async () => {}, listThreads: async (options: { cursor?: string } = {}) => ({ backend: 'app-server', limit: 1, nextCursor: options.cursor, threads: [] }) } as unknown as ChatGptDesktopAdapter); + expect(await listThreadsOperation(listThreadsSchema.parse({ cursor: 'previous' }))).toMatchObject({ nextCursor: 'previous', exitCode: 0 }); +}); + +it('reserves first-page space for remote rows without skipping local cursor rows', async () => { + const row = (id: string) => ({ threadId: `local:${id}`, title: id, pinned: false, selected: false, kind: 'codex' }); + const appCalls: Array<{ limit?: number; cursor?: string }> = []; + const facade = new ChatGptDesktopFacade({ + connect: async () => {}, + listThreads: async () => ({ backend: 'cdp', limit: 5, threads: [{ ...row('cdp-remote'), location: 'remote', hostId: 'host', hostName: null }] }), + } as unknown as ChatGptDesktopAdapter, 9222, { + listThreads: async (options: { limit?: number; cursor?: string }) => { + appCalls.push(options); + const start = Number(options.cursor ?? 0); + const count = options.limit ?? 5; + return { backend: 'app-server', limit: count, nextCursor: String(start + count), + threads: Array.from({ length: count }, (_, i) => row(`local-${start + i}`)) }; + }, + listRemoteThreads: () => [{ ...row('state-remote'), location: 'remote', hostId: 'host', hostName: null }], + } as never); + const first = await facade.listThreads({ limit: 5 }); + const second = await facade.listThreads({ limit: 5, cursor: first.nextCursor! }); + expect(first.threads).toHaveLength(5); + expect(first.threads.filter((thread) => thread.location === 'remote')).toHaveLength(2); + expect(appCalls).toMatchObject([{ limit: 3 }, { limit: 5, cursor: '3' }]); + expect(second.threads[0].threadId).toBe('local:local-3'); +}); + +it('pages remote rows before local rows when the page is smaller than remote inventory', async () => { + const row = (id: string) => ({ threadId: `local:${id}`, title: id, pinned: false, selected: false, kind: 'remote', location: 'remote' as const, hostId: 'host', hostName: null }); + const facade = new ChatGptDesktopFacade({ connect: async () => {}, listThreads: async () => ({ backend: 'cdp', limit: 200, threads: [] }) } as unknown as ChatGptDesktopAdapter, 9222, { + listThreads: async ({ cursor }: { cursor?: string }) => ({ backend: 'app-server', limit: 1, nextCursor: null, + threads: [{ threadId: `local:${cursor ? 'next' : 'first'}`, title: 'local', pinned: false, selected: false, kind: 'codex' }] }), + listRemoteThreads: () => [row('remote-a'), row('remote-b')], + } as never); + const first = await facade.listThreads({ limit: 1 }); + const second = await facade.listThreads({ limit: 1, cursor: first.nextCursor! }); + const third = await facade.listThreads({ limit: 1, cursor: second.nextCursor! }); + expect(first.threads[0].threadId).toBe('local:remote-a'); + expect(second.threads[0].threadId).toBe('local:remote-b'); + expect(third.threads[0].threadId).toBe('local:first'); +}); + +it('reports CDP unreachable even when app-server is reachable', async () => { + const facade = new ChatGptDesktopFacade({ status: async () => ({ reachable: false, host: '127.0.0.1', port: 9333, message: 'CDP down', exitCode: 1 }) } as unknown as ChatGptDesktopAdapter, 9333, { statusProbe: async () => ({ reachable: true }) } as never); + expect(await facade.status()).toMatchObject({ reachable: false, exitCode: 1, appServerFallback: { reachable: true } }); + setChatGptDesktopAdapterForTests({ connect: async () => {}, close: async () => {}, status: async () => facade.status() } as unknown as ChatGptDesktopAdapter); + expect(await statusOperation({})).toMatchObject({ reachable: false, exitCode: 1 }); +}); + +it('hovers then dispatches a real project button press and release', async () => { + expect(startNewChatExpression('core')).toContain('scrollIntoView'); + const sent: string[] = []; + const session = { + evaluate: async (expression: string) => expression.includes('getComputedStyle') + ? { x: 12, y: 14, visible: true } + : { ok: true, via: 'project', hoverX: 8, hoverY: 10 }, + send: async (_method: string, params: { type: string }) => { sent.push(params.type); }, + }; + await startNewChatInDom(session as never, 'page', { project: 'core' }); + expect(sent).toEqual(['mouseMoved', 'mouseMoved', 'mousePressed', 'mouseReleased']); +}); + +it('uses the displayed durable id before sidebar lookup and routes missing rows', async () => { + const expressions: string[] = []; + const session = { evaluate: async (expression: string) => { + expressions.push(expression); + if (expression === CONVERSATION_ID_EXPRESSION) return expressions.length === 1 ? 'already-open' : ''; + if (expression.includes('router.navigate')) return { ok: true }; + return { ok: false, error: 'thread-not-found' }; + } }; + await openThreadInDom(session as never, 'page', 'local:already-open'); + expect(expressions).toEqual([CONVERSATION_ID_EXPRESSION]); + await openThreadInDom(session as never, 'page', 'local:missing-row'); + expect(expressions.at(-1)).toContain("/local/missing-row"); + expect(navigateToThreadExpression('local:missing-row')).toContain('router.navigate'); +}); + +it('orders full CDP history oldest first and deduplicates stable turn keys', async () => { + let harvests = 0; + const session = { + evaluate: async (expression: string) => { + if (expression.includes('getBoundingClientRect')) return { ok: true, x: 10, y: 10 }; + if (expression.includes('gapPrefix')) return harvests++ === 0 + ? [{ turnKey: 'history-content:turn:new', role: 'assistant', text: 'new' }] + : [{ turnKey: 'history-content:turn:old', role: 'user', text: 'old' }, { turnKey: 'history-content:turn:new', role: 'assistant', text: 'new' }]; + return {}; + }, + send: async () => {}, + }; + const turns = await readTurnsFromDom(session as never, 'page', { full: true, limit: 10, idleWheels: 1, maxWheels: 2 }); + expect(turns.map((turn) => turn.turnKey)).toEqual(['history-content:turn:old', 'history-content:turn:new']); +}); + +it('reports an archived route distinctly from a loading timeout', async () => { + const session = { evaluate: async (expression: string) => expression === ARCHIVED_THREAD_EXPRESSION ? true : expression === LOADING_TASK_GONE_EXPRESSION }; + await expect(waitForLoadingTaskGone(session as never, 'page', { threadId: 'local:archived', timeoutMs: 1000 })).rejects.toThrow('archived'); +}); diff --git a/tests/route-unit/chatgpt-desktop-review.test.ts b/tests/route-unit/chatgpt-desktop-review.test.ts index ca661c9..f68bdab 100644 --- a/tests/route-unit/chatgpt-desktop-review.test.ts +++ b/tests/route-unit/chatgpt-desktop-review.test.ts @@ -4,7 +4,7 @@ import { afterEach, expect, it, rstest } from '@rstest/core'; import { CdpSession } from '../../src/core/chatgpt-desktop/cdp-session.js'; import { CdpChatGptDesktopAdapter } from '../../src/core/chatgpt-desktop/cdp-adapter.js'; import { ChatGptDesktopFacade, finalizeThreadList, setChatGptDesktopAdapterForTests } from '../../src/core/chatgpt-desktop/facade.js'; -import { CONVERSATION_ID_EXPRESSION, REPLY_STATE_EXPRESSION, LOADING_TASK_GONE_EXPRESSION, waitForReplyDone } from '../../src/core/chatgpt-desktop/cdp-dom.js'; +import { ARCHIVED_THREAD_EXPRESSION, CONVERSATION_ID_EXPRESSION, REPLY_STATE_EXPRESSION, LOADING_TASK_GONE_EXPRESSION, waitForReplyDone } from '../../src/core/chatgpt-desktop/cdp-dom.js'; import { sendSchema, waitSchema } from '../../src/core/codex/routes.js'; import { statusOperation } from '../../src/core/chatgpt-desktop/routes.js'; import type { ChatGptDesktopAdapter } from '../../src/core/chatgpt-desktop/adapter.js'; @@ -58,8 +58,9 @@ async function connectedAdapter(state: Record, open = true) { : { sessionId: 'page' }) as never); rstest.spyOn(CdpSession.prototype, 'evaluate').mockImplementation(async expression => { if (expression === REPLY_STATE_EXPRESSION) return state as never; - if (expression === CONVERSATION_ID_EXPRESSION) return 'thread' as never; + if (expression === CONVERSATION_ID_EXPRESSION) return (open ? 'thread' : 'other') as never; if (expression === LOADING_TASK_GONE_EXPRESSION) return true as never; + if (expression.includes('router.navigate')) return { ok: false } as never; return { ok: open, error: 'thread-not-found' } as never; }); const adapter = new CdpChatGptDesktopAdapter(); @@ -100,7 +101,7 @@ it('serializes Desktop operations and closes each connection on completion', asy it('waits through an old conversation rendered before Loading task appears', async () => { const { waitForLoadingTaskGone } = await import('../../src/core/chatgpt-desktop/cdp-dom.js'); let reads = 0; - const session = { evaluate: async (expression: string) => expression === CONVERSATION_ID_EXPRESSION ? (++reads === 1 ? 'old-thread' : 'wanted-thread') : true }; + const session = { evaluate: async (expression: string) => expression === CONVERSATION_ID_EXPRESSION ? (++reads === 1 ? 'old-thread' : 'wanted-thread') : expression !== ARCHIVED_THREAD_EXPRESSION }; await waitForLoadingTaskGone(session as never, 'page', { timeoutMs: 600, threadId: 'local:wanted-thread' }); expect(reads).toBe(2); }); diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index 77f7237..bdb6edf 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -283,7 +283,7 @@ describe('chatgpt-desktop thread id mapping', () => { ], }, ); - expect(merged.backend).toBe('app-server'); + expect(merged.backend).toBe('app-server+cdp'); expect(merged.threads[0]).toMatchObject({ threadId: 'local:11111111-1111-1111-1111-111111111111', title: 'from app-server', @@ -612,7 +612,7 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () const listed = await facade.listThreads({ limit: 5 }); expect(listed).toMatchObject({ - backend: 'app-server', + backend: 'app-server+cdp', threads: [ { threadId: 'local:11111111-1111-1111-1111-111111111111', @@ -625,7 +625,7 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () const searched = await facade.searchThreads({ query: 'app-server', limit: 5 }); expect(searched).toMatchObject({ - backend: 'app-server', + backend: 'app-server+cdp', query: 'app-server', threads: [{ selected: true, project: 'Launch' }], }); @@ -659,9 +659,9 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () expect(opened).toMatchObject({ backend: 'cdp' }); expect(calls).toEqual([ - 'app-server.listThreads', 'cdp.connect', 'cdp.listThreads', + 'app-server.listThreads', 'app-server.searchThreads', 'cdp.listThreads', 'app-server.readThread', @@ -762,6 +762,7 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () turns: [{ turnKey: 't1', role: 'assistant', text: 'fallback reply' }], }), statusProbe: async () => ({ reachable: true, mode: 'daemon', socketPath: '/tmp/fake.sock' }), + listRemoteThreads: () => [], }, ); @@ -780,10 +781,9 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () const status = await facade.status(); expect(status).toMatchObject({ - reachable: true, + reachable: false, appServerFallback: { reachable: true, mode: 'daemon' }, - message: 'CDP unreachable; Codex app-server available for list/search/read', - exitCode: 0, + exitCode: 1, }); }); @@ -815,6 +815,7 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () throw new Error('unused'); }, statusProbe: async () => ({ reachable: false }), + listRemoteThreads: () => [], }, ); const listed = await facade.listThreads(); @@ -1028,7 +1029,7 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () }, ); const hostList = await facade.listHosts(); - expect(hostList.hostsSource).toBe('remote-thread-summaries-v3+local'); + expect(hostList.hostsSource).toBe('local+remote-thread-summaries-v3+managed-connections'); expect(hostList.modelProvidersSource).toBe('thread/list-distinct'); expect(hostList.modelProviders).toEqual(['anthropic', 'openai']); expect(hostList.hosts.find((h) => h.hostId === 'local')?.threadCount).toBe(1); From 2718be5287f34270de0303875fce6da29d4236ec Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 28 Sep 2026 20:53:16 -0700 Subject: [PATCH 23/26] Expose complete ChatGPT Desktop MCP workflow and skill --- .changeset/desktop-e2e-reliability.md | 2 +- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 181 ++++++- artifact/bin/gbot.mjs | 205 +++++++- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 470 +++++++++++++----- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 457 +++++++++++++---- artifact/skills/chatgpt-desktop/SKILL.md | 60 +++ docs/chatgpt-desktop-cdp.md | 19 +- src/cli/chatgpt-desktop/search.tsx | 2 + src/cli/chatgpt-desktop/send.tsx | 3 + src/cli/chatgpt-desktop/threads.tsx | 2 + src/core/chatgpt-desktop/adapter.ts | 3 + .../chatgpt-desktop/app-server-fallback.ts | 22 +- src/core/chatgpt-desktop/cdp-adapter.ts | 9 +- src/core/chatgpt-desktop/cdp-dom.ts | 4 +- src/core/chatgpt-desktop/errors.ts | 26 + src/core/chatgpt-desktop/facade.ts | 47 +- src/core/chatgpt-desktop/index.ts | 2 + src/core/chatgpt-desktop/routes.ts | 29 +- src/core/chatgpt-desktop/types.ts | 2 + .../tools/chatgpt_desktop_list_hosts.tsx | 2 +- .../tools/chatgpt_desktop_list_threads.tsx | 7 +- .../tools/chatgpt_desktop_open_thread.tsx | 39 ++ .../tools/chatgpt_desktop_read_thread.tsx | 4 +- .../tools/chatgpt_desktop_search_threads.tsx | 5 +- .../grok-bot/tools/chatgpt_desktop_send.tsx | 7 +- .../grok-bot/tools/chatgpt_desktop_status.tsx | 2 +- .../tools/chatgpt_desktop_wait_reply.tsx | 6 +- src/skills/chatgpt-desktop/SKILL.md | 60 +++ test/host-tool-inventory.test.js | 32 ++ .../chatgpt-desktop-e2e-regressions.test.ts | 9 + .../chatgpt-desktop-mcp-followup.test.ts | 162 ++++++ tests/route-unit/chatgpt-desktop.test.ts | 1 + tests/route-unit/tools.test.ts | 2 +- 35 files changed, 1587 insertions(+), 300 deletions(-) create mode 100644 artifact/skills/chatgpt-desktop/SKILL.md create mode 100644 src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx create mode 100644 src/skills/chatgpt-desktop/SKILL.md create mode 100644 tests/route-unit/chatgpt-desktop-mcp-followup.test.ts diff --git a/.changeset/desktop-e2e-reliability.md b/.changeset/desktop-e2e-reliability.md index a4f7527..38a3250 100644 --- a/.changeset/desktop-e2e-reliability.md +++ b/.changeset/desktop-e2e-reliability.md @@ -2,4 +2,4 @@ "grok-bot-cli": patch --- -Fix ChatGPT Desktop host discovery, bounded thread reads and searches, list pagination, CDP navigation and project clicks, status reachability, and result provenance. +Fix ChatGPT Desktop host discovery, bounded thread reads and searches, list pagination, CDP navigation and project clicks, status reachability, and result provenance. Add complete MCP and skill guidance, project filters, archived-thread reads and explicit unarchive-on-send support. diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 97e1959..2b1ddc4 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"b232ed66e778ef4abba677ef20f60d1c47a834ab3741e526a38ced3b2098b126"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"eaf64010acbeac8278b2f8ba77977cabf96ef0b4bc2c52c7cacf6d41010a870b"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"abb8db232326732759af2a555de555cd1af4beebeb082c5ebca214ff2fc713f3"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"9c8bbfa57c9937aed83ee0c3efecaf970cb41d24db3d7fb135d2b33d24d63677"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"4c189f7e866020f7e9265ce684da2d47a0f75feabc9a5c1d6f60098c31924064"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"ed957e4c740861191c60d07b4e0b664c3a0894b9999dd16a14577cd86de23c3e"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"b4788c931e14fe9472988d847ff58c09a0e3ea6963a12192eaf49e46687fb878"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"c477b441f64327117257b27c3b4fa31431e647bfd8806bb806b64a6df42453c5"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"dbbe31470fff7f20f3298d84e278e33fc3bc3c16813904a8b250f601a213ff03"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"4c189f7e866020f7e9265ce684da2d47a0f75feabc9a5c1d6f60098c31924064"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 42860ba..164291f 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"04cadea34351c5aa9b548241ec2a0dd7e47ca671cb716cb2a39a43198aa5d48b","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"61cd412ae47654cc8536e53abfa87cab5c51c9e3d844f97aaab595bd0796c6e1","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/desktop-e2e-reliability.md","sha256":"6fee865161991ceca89a10e49f4721326257bb03ff431c1016cf23e2319318b3"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"30aaeac24084f0a642d811aa493fc51b0fd3eddff322d359c39c573d8394ff3e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"4e11165ccdca7507a643e7670a56e9dcbdfb77305b4d33bd12c6008513349426"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"a322d4cfa34f3a2603c4233c13a8e47be4b939bc5d4d9dff46a757b2289665dc"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"96a40c973cc536f6ac123115d57e359d35e1b2763c4be96ebe8d776cd690feea"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"5cdd948062f0ba15af16917870c74d77259ed97af008d15bce95095e246129c9"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"0a70d4937c6ffc19397adedd301c19d973592f0a97347cd7e53d855b35ac556c"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"8c62b1750a8864f8c6d95ea1ce724b94a77b08de2dc4a052e1b8d6e935966485"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"a5414d9209bf529323dcc399c1bacf6287689f9bed5158239136305bd928949d"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"a71de63de0a5d9921263262958960a6ea2032864f82d41ccff3aa374c6598799"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"1a3610381f04a8b0f231466229e5bf0628bc9f7b7f794e5d1dcb4bb4515983fd"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"a33860336ea2c336d2f0a17168502f8dad37bce7de671ebc826a1652fd69c196"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"23f6f428693da5c3e638050ab97289ff48333a0be1874f425a837f1f28a21bd8"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"7e811d3ecfe92620b19dbef05195948adc93f7547103968d7cf25944cd1a113f"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"ed93418ff5d2bb51016783e7b0a458805e709b212974a66be804ddb9f7038033"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"55cc7b6ccd125894bf52ddc00fa5bae044227088594d0711333de0e736ec8ea2"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"ca0eb69a76895840fb8c84ed5e75d27d8a26a09c61158ea364882b4dcf060878"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"d398fd4a1ecff32c58084a9e1c6266e8f6cf2db7ef29777a44d43e2ef0196ddd"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"52565007799e98c3bff4297287d8e53005e285a95bab9e4e4d0a088bded4fa8e"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"f4d5e0377cdb7297754d3220c1935fc65bfb5f605b3bc0f15f5ff328f0ce3b63"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"30af9ffb3e8ed8679c3c290f3d75bd54825f9d9cdaec9e22e10b6fd2f84817c1"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"b0fbcdb613dd9d8410ea9eb96dae8b5b8a9633e4c813bc9cff24b8355de1c0fd"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"04fbbcaf2b52cbdb0aef156429a5be2a66c950767c1d6d68cbf472fa92380bff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"bb02dcc5f664ed62c28b4ce55c5f5bfb0e0ab57c89446bb50e12eb57cd1757ff"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"4f30ca5b87ab0f0db91ad40548772bfc2c15f1abd69d3beff0e267bda0c4186d"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"0c3e7d25eb06f21ab82ac0c09e22cee1a13fcc602dffdd1c5508a84cce5abb71"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"e1cedeacf6834be92d1e4009ae66fa10dbcde7f8f56f9558855f5ffd846ed5cc"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"cdeb0f18c938e13facf467c1b4364394ed799c87b2d4b4566508c527efc6bef4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"5fe86e3673ae993dd1b4eff814699be9c164d99dc17bd229b9154949534fee47"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts","sha256":"85bd7fdfcc0c6b52deb796f97897b07edc03e0a9d5669b323341f33db42c096c"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"208dfdea18ccc408a279666a521d2f70fdce9bdaf28f86bc5d053f7ad09a7dd2"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"810be6a2ec5ec02295f373e2a335b9a38d49d354832e6a707bb45b88f90a3c9d"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"b671db62ea723a21e11f69ba4b857e271573db22dd61aeb1d152b989824df5cb"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22276,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"ab45c9b3ef6e5a79e8da9e13ae8a57d8dfb9269f120ec4dc850578f80fa0cd93"},{"bytes":1533419,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"b232ed66e778ef4abba677ef20f60d1c47a834ab3741e526a38ced3b2098b126"},{"bytes":2398279,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"eaf64010acbeac8278b2f8ba77977cabf96ef0b4bc2c52c7cacf6d41010a870b"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1453666,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"abb8db232326732759af2a555de555cd1af4beebeb082c5ebca214ff2fc713f3"},{"bytes":3280217,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"9c8bbfa57c9937aed83ee0c3efecaf970cb41d24db3d7fb135d2b33d24d63677"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1299066,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"4c189f7e866020f7e9265ce684da2d47a0f75feabc9a5c1d6f60098c31924064"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Recent default 100; full default 2000","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a previous page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"07eaaacda7d8c988d5bc2fd40cdfec2a80980d0cc7491b6b626391207cbed0bb","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover local, remote-control, and managed SSH hosts from Desktop state, including nested remote-thread summaries. Host names are null when Desktop has no display name. Providers come from paged app-server inventory and remote summaries. Result includes sources and discovery warnings.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"Page ChatGPT Desktop / Codex threads with cursor and nextCursor. Merges local app-server rows, CDP sidebar rows, and nested remote-control summaries. Discover dynamic host and modelProvider filters via chatgpt_desktop_list_hosts. Optional groupBy=host. Result reports the contributing backends and warnings.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum threads (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read paged ChatGPT Desktop turns through app-server, including userText, assistantText, and completedAt as endedAt. Remote-only threads return REMOTE_THREAD_NOT_LOADED with hostId. CDP fallback reports complete:false and a warning when app-server fails. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"Desktop sidebar id (local:) or bare app-server thread id.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"description":"Maximum matches (1-200).","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"Preferred project for new chats (Start new chat in ).","type":"string"},"text":{"type":"string"},"threadId":{"description":"Sidebar thread id; omit to start a new chat.","type":"string"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"0bf417d16a1274518c81ab4fac1b5894661407b0a2f7811cb61d0397ff0b08d6","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"71722c08f258cdb5ffb1720702c5aa9727816abb19c16d2d3b88a608506833be","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/desktop-e2e-reliability.md","sha256":"471d89f0ba5e7be136121f52aaf404c26fa6532a67409928ab3e2c69bcd2cd02"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"30aaeac24084f0a642d811aa493fc51b0fd3eddff322d359c39c573d8394ff3e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"79cfd378c2c35c51d021d1d91c9c21b26479eb7a0f99d756cdc08627e90c5df3"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"a322d4cfa34f3a2603c4233c13a8e47be4b939bc5d4d9dff46a757b2289665dc"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"91c4bf8292dea3e2066272c90f36a2882ab8b9e5bca004c2c21a68d5aaea083c"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"b801a028980e60fe37dca56e86887a1e2b0b8ce80ce77b379e7375d2e4544d5e"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"d0a33935d992af349c52ef448622da5e460b4af1a9474aac60994295245b43ad"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"a8affca89c97739995976fed02bc1432abe6f3f5beba11df6dd5e1eca044af1c"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"d20d44e1bed831eeed6e82afaac60c3e7b5d1b7753c1ec4611d76e12dbe51a46"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"e8712876dc3dc28e5bd687191400b8f593f0711588e23bd8f378fabc7f7f970a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"95322209490160d04fc52a4dfa43f2691b4c4720a7121a3f3686c9f7eb4fbbb8"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"2ec693a70f8d004e0c9ae5abb24d49b31d8c49d64dc2b96037cc32e80de3199d"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"27bbd41043d0f07bcff9825f9a85d85d216663ec98781dd38f1a54c5a3352a15"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"591e6968c008cc75827da94b91c0ea15e573640876814e35e2470342dc8bccf9"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"ed93418ff5d2bb51016783e7b0a458805e709b212974a66be804ddb9f7038033"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"824191e3c4189dcc4d68e846a8f147f91714dbbb93fdbbcbb497c0e4681846c6"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"029ed893a93f9e3660235df93eece60cbb8af5b7aba37ab3d0d677e418489895"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"d398fd4a1ecff32c58084a9e1c6266e8f6cf2db7ef29777a44d43e2ef0196ddd"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"52565007799e98c3bff4297287d8e53005e285a95bab9e4e4d0a088bded4fa8e"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"f4d5e0377cdb7297754d3220c1935fc65bfb5f605b3bc0f15f5ff328f0ce3b63"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"86334421686350ea044fb1160c19b6f5889425feb78fd608675feb8137492090"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"568ad7621546d422a7f7227b429f80bea8a8e2fb5211f1c8cc1f9ced7651d2bc"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","sha256":"b415d5bd303693649abae96b6b9d2920d29c797f5367ae8fbb2b62b635528e37"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"6b51a60a6f7bfeb7fb3882661035137b44cb3eaf6895560e7a1e53a4c8fd6d0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"71070b1734fc4ae1a48ec5878a05bdf5741785111ba4ca1f8af72f0d96734da6"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"cf1cb83c76bb46da6245fe447f811ab6f9a2d4b0b94f21d8fbea97ac324714b1"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"681e50ae6c7d3a04a76ad8eadf865ab9d793b5eb3c78f961a42d0902adacc306"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"2786b62ff2a1a4e68229199935ac63c15614a0f0bdbef74b2d06e0c405516272"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/chatgpt-desktop/SKILL.md","sha256":"ee23320518e1b8144974d26ef43d96e2de302aa413d2b298bfcd65a2c8a85433"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"cdeb0f18c938e13facf467c1b4364394ed799c87b2d4b4566508c527efc6bef4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"a869553b1f299db8c7ddf6a5e732e50df49d7ecc91aaffddd0d6b3e54ee38578"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts","sha256":"1a5da468713ff765dee4a8324a68d5952621fee5d8b817859e2b56202e579edf"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-mcp-followup.test.ts","sha256":"83c8f33a4c5e1243e353163d864e1fdd2cf0e6564ac5ac71366f01efec952398"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"208dfdea18ccc408a279666a521d2f70fdce9bdaf28f86bc5d053f7ad09a7dd2"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"88904d9d13f2449270ab3275aba933019aae6579d75a74621cdf936cd5a1f959"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"c5bb9ab56b7806fcc899df9466645f1eeed8a3cee92a95506d8efeb640018c84"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/chatgpt-desktop/SKILL.md","sourceInputs":["src/skills/chatgpt-desktop/SKILL.md"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22276,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"bb563d8ce6554a02e5de4706a24aa0c7c1e9c6e4c113547559e29f352bbea07d"},{"bytes":1540128,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"ed957e4c740861191c60d07b4e0b664c3a0894b9999dd16a14577cd86de23c3e"},{"bytes":2406223,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"b4788c931e14fe9472988d847ff58c09a0e3ea6963a12192eaf49e46687fb878"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1467923,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"c477b441f64327117257b27c3b4fa31431e647bfd8806bb806b64a6df42453c5"},{"bytes":3294851,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"dbbe31470fff7f20f3298d84e278e33fc3bc3c16813904a8b250f601a213ff03"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1299066,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"4c189f7e866020f7e9265ce684da2d47a0f75feabc9a5c1d6f60098c31924064"},{"bytes":3691,"kind":"copy","path":"skills/chatgpt-desktop/SKILL.md","sha256":"ee23320518e1b8144974d26ef43d96e2de302aa413d2b298bfcd65a2c8a85433"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Recent default 100; full default 2000","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false},{"description":"Explicitly unarchive an existing archived thread before sending.","key":"unarchive","kind":"boolean","option":"unarchive","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a previous page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_open_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"24078e6fa9b1d6694669ef83b935343f6857d87497e6817555ae4184e11d5da3","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover local, remote-control environment ids, managed SSH hosts, and modelProvider ids. hostName is null when Desktop has no real display name. Use hostId or label in list/search filters; remote thread ids must be read on the owning host. warnings report provider discovery failures.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List Desktop threads, then pass nextCursor as cursor until null. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","description":"Navigate Desktop to an existing local: or bare conversation id, even when the row is absent from the sidebar. Archived routes return archived:true without unarchiving; read them with chatgpt_desktop_read_thread. A remote-control id is owned by its hostId and cannot be opened on this Mac. CDP_UNREACHABLE means Desktop must be reachable locally.","id":"tool:grok-bot/chatgpt_desktop_open_thread","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Recent defaults to 100 turns; full pages up to 2000 from the start. Archived threads remain readable. complete:false means partial history; warnings preserve app-server/frame errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search Desktop thread metadata by case-insensitive substring. Dynamic hostId/hostName, modelProvider, and project filters apply. Search scans bounded app-server pages and reports warnings if incomplete; use list_threads cursor for exhaustive paging. Remote results identify hostId and cannot be read on this Mac.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Check local ChatGPT Desktop CDP before send, wait, or open. reachable:false and exitCode:1 mean CDP is down even if appServerFallback.reachable is true; list/search/read may still work through app-server. There is no remote CDP transport.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"After chatgpt_desktop_send, wait for the selected Desktop reply over CDP. Accept the returned durable local: or the temporary local:client-new-thread:* while selected; omit threadId only when staying on the same selected chat. Returns reply, durable threadId and conversationId. timeout is not proof the send failed; CDP_UNREACHABLE requires Desktop recovery. Remote ids must be handled on their hostId.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index 22bf562..2d7c785 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -8766,6 +8766,10 @@ var __webpack_modules__ = { description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' }, + project: { + description: 'Project label or projectId filter.', + type: 'string' + }, port: { description: 'Local CDP port', type: 'number' @@ -8785,6 +8789,7 @@ var __webpack_modules__ = { host: zod__rspack_import_2.YjP().min(1).max(256).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), modelProvider: zod__rspack_import_2.YjP().min(1).max(256).optional(), + project: zod__rspack_import_2.YjP().min(1).max(256).optional(), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), query: zod__rspack_import_2.YjP().min(1).max(512) }).strict(); @@ -8837,6 +8842,10 @@ var __webpack_modules__ = { }, threadId: { type: 'string' + }, + unarchive: { + type: 'boolean', + description: 'Explicitly unarchive an existing archived thread before sending.' } }, required: [ @@ -8853,7 +8862,8 @@ var __webpack_modules__ = { port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), project: zod__rspack_import_2.YjP().min(1).max(256).optional(), text: zod__rspack_import_2.YOg(zod__rspack_import_2.YjP()).min(1), - threadId: zod__rspack_import_2.YjP().min(1).max(256).optional() + threadId: zod__rspack_import_2.YjP().min(1).max(256).optional(), + unarchive: zod__rspack_import_2.zMY().default(false) }).strict(); async function chatgptDesktopSend({ input }) { const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.UP)({ @@ -8861,6 +8871,7 @@ var __webpack_modules__ = { threadId: input.threadId, text: input.text.join(' ').trim(), project: input.project, + unarchive: input.unarchive, openTimeoutMs: input.openTimeoutMs }); return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { @@ -8954,6 +8965,10 @@ var __webpack_modules__ = { description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' }, + project: { + description: 'Project label or projectId filter.', + type: 'string' + }, port: { description: 'Local CDP port', type: 'number' @@ -8968,6 +8983,7 @@ var __webpack_modules__ = { limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), cursor: zod__rspack_import_2.YjP().min(1).max(4096).optional(), modelProvider: zod__rspack_import_2.YjP().min(1).max(256).optional(), + project: zod__rspack_import_2.YjP().min(1).max(256).optional(), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() }).strict(); async function chatgptDesktopThreads({ input }) { @@ -11293,7 +11309,7 @@ var __webpack_modules__ = { modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } - async function appServerSearchThreads({ query, limit = 50, modelProviders = [] }) { + async function appServerSearchThreads({ query, limit = 50, modelProviders = [], project }) { const needle = query.trim().toLowerCase(); if (!needle) { return appServerListThreads({ @@ -11312,7 +11328,10 @@ var __webpack_modules__ = { }); for (const thread of out.threads){ const mapped = mapListedThread(thread); - if (threadMatchesQuery(mapped, needle)) matched.push(mapped); + if (threadMatchesQuery(mapped, needle) && (!project || [ + mapped.project, + mapped.projectId + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase())))) matched.push(mapped); if (matched.length >= limit) break; } if (out.nextCursor == null || typeof out.nextCursor !== 'string') { @@ -11393,6 +11412,20 @@ var __webpack_modules__ = { throw maybeRemoteThreadError(error, bare); } } + async function appServerUnarchiveThread(threadId) { + const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + const result = await client.request('thread/unarchive', { + threadId: bare + }); + if (!result || typeof result !== 'object' || !('thread' in result) || !result.thread || typeof result.thread !== 'object' || !('id' in result.thread) || result.thread.id !== bare) { + throw new Error(`thread/unarchive returned no thread for ${bare}`); + } + } finally{ + client.close(); + } + } async function readLocalThread(bare, { limit, full }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { @@ -11665,7 +11698,8 @@ var __webpack_modules__ = { OI: ()=>appServerListThreads, X: ()=>discoverModelProviders, aI: ()=>appServerSearchThreads, - dM: ()=>appServerStatusProbe + dM: ()=>appServerStatusProbe, + qL: ()=>appServerUnarchiveThread }); }, "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -11822,7 +11856,16 @@ var __webpack_modules__ = { } async openThread(threadId, { openTimeoutMs = 90000 } = {}) { const sessionId = await this.#ensurePageSession(); - await this.#openAndWait(sessionId, threadId, openTimeoutMs); + try { + await this.#openAndWait(sessionId, threadId, openTimeoutMs); + } catch (error) { + if (error instanceof _errors_js__rspack_import_0.fw) return { + threadId, + backend: 'cdp', + archived: true + }; + throw error; + } return { threadId, backend: 'cdp' @@ -11910,7 +11953,8 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var _codex_thread_id_js__rspack_import_0 = __webpack_require__("./src/core/codex/thread-id.js"); + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _codex_thread_id_js__rspack_import_1 = __webpack_require__("./src/core/codex/thread-id.js"); const MAIN_WINDOW_URL = 'app://-/index.html'; const IGNORED_TARGET_URL_MARKERS = [ 'initialRoute=%2Favatar-overlay', @@ -12000,20 +12044,20 @@ var __webpack_modules__ = { ]; } function durableThreadKey(threadId) { - if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + if ((0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) return threadId; try { - return (0, _codex_thread_id_js__rspack_import_0.SX)(threadId); + return (0, _codex_thread_id_js__rspack_import_1.SX)(threadId); } catch { return threadId.startsWith("local:") ? threadId.slice("local:".length) || threadId : threadId; } } function toDesktopForm(threadId) { - if (!threadId || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + if (!threadId || (0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) return threadId; if (threadId.startsWith("local:")) return threadId; return `${"local:"}${threadId}`; } function preferThreadRow(left, right) { - const score = (row)=>(row.selected ? 4 : 0) + (row.pinned ? 2 : 0) + (row.threadId.startsWith("local:") && !(0, _codex_thread_id_js__rspack_import_0.vr)(row.threadId) ? 1 : 0); + const score = (row)=>(row.selected ? 4 : 0) + (row.pinned ? 2 : 0) + (row.threadId.startsWith("local:") && !(0, _codex_thread_id_js__rspack_import_1.vr)(row.threadId) ? 1 : 0); return score(right) > score(left) ? right : left; } const LIST_THREADS_EXPRESSION = `(() => { @@ -12251,7 +12295,7 @@ var __webpack_modules__ = { async function openThreadInDom(session, sessionId, threadId) { const current = await readConversationIdFromDom(session, sessionId); if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; - if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + if ((0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { limit: 200 }); @@ -12261,7 +12305,7 @@ var __webpack_modules__ = { sessionId }); if (!result?.ok) { - if (result?.error === 'thread-not-found' && !(0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + if (result?.error === 'thread-not-found' && !(0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) { const navigated = await session.evaluate(navigateToThreadExpression(threadId), { sessionId }); @@ -12281,7 +12325,7 @@ var __webpack_modules__ = { }) === true) { archivedSince ??= Date.now(); if (Date.now() - archivedSince >= 500) { - throw new Error(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived; unarchive it in Desktop before opening`); + throw new _errors_js__rspack_import_0.fw(threadId); } } else { archivedSince = null; @@ -12294,12 +12338,12 @@ var __webpack_modules__ = { const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; lastConversationId = current; if (!threadId) return; - if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { limit: 200 }); const selected = rows.find((row)=>row.selected); - if (!current && (!selected || (0, _codex_thread_id_js__rspack_import_0.vr)(selected.threadId))) return; + if (!current && (!selected || (0, _codex_thread_id_js__rspack_import_1.vr)(selected.threadId))) return; } else if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; } await delay(250); @@ -12368,6 +12412,7 @@ var __webpack_modules__ = { sessionId }); if (!focused?.ok) { + if (focused?.error === 'composer-has-draft') throw new _errors_js__rspack_import_0.oN(); throw new Error(`ChatGPT Desktop composer unavailable: ${focused?.error || 'not found'}`); } } @@ -12445,7 +12490,7 @@ var __webpack_modules__ = { const deadline = Date.now() + timeoutMs; while(Date.now() < deadline){ const id = await readConversationIdFromDom(session, sessionId); - if (id && !(0, _codex_thread_id_js__rspack_import_0.vr)(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { + if (id && !(0, _codex_thread_id_js__rspack_import_1.vr)(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { return id; } await delay(200); @@ -12453,10 +12498,10 @@ var __webpack_modules__ = { throw new Error(`ChatGPT Desktop conversation id did not appear on [data-response-annotation-conversation] within ${timeoutMs}ms`); } function resolveDurableThreadId(conversationId, fallbackThreadId) { - if (conversationId && !(0, _codex_thread_id_js__rspack_import_0.vr)(conversationId)) { + if (conversationId && !(0, _codex_thread_id_js__rspack_import_1.vr)(conversationId)) { return toDesktopForm(conversationId); } - if (fallbackThreadId && !(0, _codex_thread_id_js__rspack_import_0.vr)(fallbackThreadId) && fallbackThreadId !== 'new') { + if (fallbackThreadId && !(0, _codex_thread_id_js__rspack_import_1.vr)(fallbackThreadId) && fallbackThreadId !== 'new') { return toDesktopForm(fallbackThreadId); } return null; @@ -12765,6 +12810,26 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); + class ArchivedThreadError extends Error { + code = 'ARCHIVED_THREAD'; + reason = 'archived-thread'; + delivery = 'rejected'; + threadId; + constructor(threadId){ + super(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived. Read it through app-server, or pass unarchive: true on send to unarchive before sending.`); + this.name = 'ArchivedThreadError'; + this.threadId = threadId; + } + } + class ComposerDraftError extends Error { + code = 'COMPOSER_HAS_DRAFT'; + reason = 'composer-has-draft'; + delivery = 'rejected'; + constructor(){ + super('ChatGPT Desktop composer contains an unsent draft; inspect it in Desktop before sending.'); + this.name = 'ComposerDraftError'; + } + } class NotImplementedError extends Error { code = 'NOT_IMPLEMENTED'; delivery = 'rejected'; @@ -12796,6 +12861,8 @@ var __webpack_modules__ = { EH: ()=>NotImplementedError, Rg: ()=>_codex_remote_control_js__rspack_import_0.Rg, c$: ()=>CdpHostRejectedError, + fw: ()=>ArchivedThreadError, + oN: ()=>ComposerDraftError, sO: ()=>CdpUnreachableError }); }, @@ -12810,6 +12877,7 @@ var __webpack_modules__ = { listThreads: _app_server_fallback_js__rspack_import_1.OI, searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, + unarchiveThread: _app_server_fallback_js__rspack_import_1.qL, statusProbe: _app_server_fallback_js__rspack_import_1.dM, listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, listHosts: _remote_threads_js__rspack_import_4.Kl, @@ -12878,6 +12946,7 @@ var __webpack_modules__ = { limit: 10000, host, modelProvider: options.modelProvider, + project: options.project, remotes }); const offset = remoteOffset ?? 0; @@ -12898,7 +12967,7 @@ var __webpack_modules__ = { } } const remoteKeys = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); - const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; + const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); let appList = null; let appError; @@ -12927,6 +12996,7 @@ var __webpack_modules__ = { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes }); @@ -13064,7 +13134,8 @@ var __webpack_modules__ = { const appList = await this.#fallbacks.searchThreads({ query: options.query, limit, - modelProviders + modelProviders, + project: options.project }); const cdpList = await this.#tryCdpList({ limit @@ -13074,6 +13145,7 @@ var __webpack_modules__ = { limit: 10000, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, remotes: this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); @@ -13086,6 +13158,7 @@ var __webpack_modules__ = { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes: [] }); @@ -13109,6 +13182,7 @@ var __webpack_modules__ = { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) }); @@ -13156,14 +13230,29 @@ var __webpack_modules__ = { } } async sendMessage(options) { + if (options.threadId) { + const remote = (0, _remote_threads_js__rspack_import_4.KI)(options.threadId); + if (remote) throw new _errors_js__rspack_import_2.Rg(options.threadId, remote.hostId, remote.hostName); + } await this.#ensureCdp(); - return this.#cdp.sendMessage(options); + try { + return await this.#cdp.sendMessage(options); + } catch (error) { + if (!(error instanceof _errors_js__rspack_import_2.fw) || !options.unarchive || !options.threadId) throw error; + await (this.#fallbacks.unarchiveThread ?? _app_server_fallback_js__rspack_import_1.qL)(options.threadId); + return this.#cdp.sendMessage({ + ...options, + unarchive: false + }); + } } async waitForReply(options) { await this.#ensureCdp(); return this.#cdp.waitForReply(options); } async openThread(threadId, options) { + const remote = (0, _remote_threads_js__rspack_import_4.KI)(threadId); + if (remote) throw new _errors_js__rspack_import_2.Rg(threadId, remote.hostId, remote.hostName); await this.#ensureCdp(); return this.#cdp.openThread(threadId, options); } @@ -13271,7 +13360,7 @@ var __webpack_modules__ = { threads: merged }; } - function finalizeThreadList(base, { limit, host = 'all', modelProvider, groupBy, remotes }) { + function finalizeThreadList(base, { limit, host = 'all', modelProvider, project, groupBy, remotes }) { const remoteById = new Map(remotes.map((thread)=>[ (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId, thread @@ -13312,6 +13401,7 @@ var __webpack_modules__ = { const filtered = merged.filter((thread)=>{ if (!hostMatches(thread, host)) return false; if (!modelProviderMatches(thread, modelProvider)) return false; + if (!projectMatches(thread, project)) return false; return true; }); const limited = filtered.slice(0, limit); @@ -13328,6 +13418,9 @@ var __webpack_modules__ = { host, ...modelProvider ? { modelProvider + } : {}, + ...project ? { + project } : {} }; if (groupBy === 'host') { @@ -13386,6 +13479,14 @@ var __webpack_modules__ = { if (!modelProvider) return true; return thread.modelProvider === modelProvider; } + function projectMatches(thread, project) { + if (!project) return true; + const needle = project.trim().toLowerCase(); + return [ + thread.project, + thread.projectId + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } function threadMatchesQuery(thread, needle) { if (!needle) return true; return [ @@ -13909,6 +14010,7 @@ var __webpack_modules__ = { cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), + project: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const searchThreadsSchema = zod__rspack_import_4.Ikc({ @@ -13917,6 +14019,7 @@ var __webpack_modules__ = { limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), + project: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const listHostsSchema = zod__rspack_import_4.Ikc({ @@ -13929,13 +14032,29 @@ var __webpack_modules__ = { full: zod__rspack_import_4.zMY().default(false), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); + const openThreadSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId, + openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) + }).strict(); const sendSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), text: zod__rspack_import_4.YjP().trim().min(1).max(100000), project: zod__rspack_import_4.YjP().min(1).max(256).optional(), + unarchive: zod__rspack_import_4.zMY().default(false), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) - }).strict(); + }).strict().refine((value)=>!value.unarchive || Boolean(value.threadId), { + message: 'unarchive requires an existing threadId', + path: [ + 'unarchive' + ] + }).refine((value)=>!value.threadId || !value.project, { + message: 'project is only for a new thread; omit threadId', + path: [ + 'project' + ] + }); const waitReplySchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), @@ -14020,6 +14139,7 @@ var __webpack_modules__ = { cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, + project: input.project, groupBy: input.groupBy })); return asResult({ @@ -14041,6 +14161,7 @@ var __webpack_modules__ = { limit: input.limit, host: input.host, modelProvider: input.modelProvider, + project: input.project, groupBy: input.groupBy }); }); @@ -14084,6 +14205,19 @@ var __webpack_modules__ = { return mapError(error); } } + async function openThreadOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.openThread(input.threadId, { + openTimeoutMs: input.openTimeoutMs + })); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } async function sendOperation(input) { try { input = sendSchema.parse(input); @@ -14091,6 +14225,7 @@ var __webpack_modules__ = { threadId: input.threadId, text: input.text, project: input.project, + unarchive: input.unarchive, openTimeoutMs: input.openTimeoutMs })); return asResult({ diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index e2a2c53..e0cbf75 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -7174,6 +7174,10 @@ var __webpack_modules__ = { description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' }, + project: { + description: 'Project label or projectId filter.', + type: 'string' + }, port: { description: 'Local CDP port', type: 'number' @@ -7193,6 +7197,7 @@ var __webpack_modules__ = { host: zod__rspack_import_2.YjP().min(1).max(256).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), modelProvider: zod__rspack_import_2.YjP().min(1).max(256).optional(), + project: zod__rspack_import_2.YjP().min(1).max(256).optional(), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), query: zod__rspack_import_2.YjP().min(1).max(512) }).strict(); @@ -7245,6 +7250,10 @@ var __webpack_modules__ = { }, threadId: { type: 'string' + }, + unarchive: { + type: 'boolean', + description: 'Explicitly unarchive an existing archived thread before sending.' } }, required: [ @@ -7261,7 +7270,8 @@ var __webpack_modules__ = { port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), project: zod__rspack_import_2.YjP().min(1).max(256).optional(), text: zod__rspack_import_2.YOg(zod__rspack_import_2.YjP()).min(1), - threadId: zod__rspack_import_2.YjP().min(1).max(256).optional() + threadId: zod__rspack_import_2.YjP().min(1).max(256).optional(), + unarchive: zod__rspack_import_2.zMY().default(false) }).strict(); async function chatgptDesktopSend({ input }) { const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_1.UP)({ @@ -7269,6 +7279,7 @@ var __webpack_modules__ = { threadId: input.threadId, text: input.text.join(' ').trim(), project: input.project, + unarchive: input.unarchive, openTimeoutMs: input.openTimeoutMs }); return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { @@ -7362,6 +7373,10 @@ var __webpack_modules__ = { description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' }, + project: { + description: 'Project label or projectId filter.', + type: 'string' + }, port: { description: 'Local CDP port', type: 'number' @@ -7376,6 +7391,7 @@ var __webpack_modules__ = { limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), cursor: zod__rspack_import_2.YjP().min(1).max(4096).optional(), modelProvider: zod__rspack_import_2.YjP().min(1).max(256).optional(), + project: zod__rspack_import_2.YjP().min(1).max(256).optional(), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional() }).strict(); async function chatgptDesktopThreads({ input }) { @@ -9701,7 +9717,7 @@ var __webpack_modules__ = { modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } - async function appServerSearchThreads({ query, limit = 50, modelProviders = [] }) { + async function appServerSearchThreads({ query, limit = 50, modelProviders = [], project }) { const needle = query.trim().toLowerCase(); if (!needle) { return appServerListThreads({ @@ -9720,7 +9736,10 @@ var __webpack_modules__ = { }); for (const thread of out.threads){ const mapped = mapListedThread(thread); - if (threadMatchesQuery(mapped, needle)) matched.push(mapped); + if (threadMatchesQuery(mapped, needle) && (!project || [ + mapped.project, + mapped.projectId + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase())))) matched.push(mapped); if (matched.length >= limit) break; } if (out.nextCursor == null || typeof out.nextCursor !== 'string') { @@ -9801,6 +9820,20 @@ var __webpack_modules__ = { throw maybeRemoteThreadError(error, bare); } } + async function appServerUnarchiveThread(threadId) { + const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + const result = await client.request('thread/unarchive', { + threadId: bare + }); + if (!result || typeof result !== 'object' || !('thread' in result) || !result.thread || typeof result.thread !== 'object' || !('id' in result.thread) || result.thread.id !== bare) { + throw new Error(`thread/unarchive returned no thread for ${bare}`); + } + } finally{ + client.close(); + } + } async function readLocalThread(bare, { limit, full }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { @@ -10073,7 +10106,8 @@ var __webpack_modules__ = { OI: ()=>appServerListThreads, X: ()=>discoverModelProviders, aI: ()=>appServerSearchThreads, - dM: ()=>appServerStatusProbe + dM: ()=>appServerStatusProbe, + qL: ()=>appServerUnarchiveThread }); }, "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -10230,7 +10264,16 @@ var __webpack_modules__ = { } async openThread(threadId, { openTimeoutMs = 90000 } = {}) { const sessionId = await this.#ensurePageSession(); - await this.#openAndWait(sessionId, threadId, openTimeoutMs); + try { + await this.#openAndWait(sessionId, threadId, openTimeoutMs); + } catch (error) { + if (error instanceof _errors_js__rspack_import_0.fw) return { + threadId, + backend: 'cdp', + archived: true + }; + throw error; + } return { threadId, backend: 'cdp' @@ -10318,7 +10361,8 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var _codex_thread_id_js__rspack_import_0 = __webpack_require__("./src/core/codex/thread-id.js"); + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _codex_thread_id_js__rspack_import_1 = __webpack_require__("./src/core/codex/thread-id.js"); const MAIN_WINDOW_URL = 'app://-/index.html'; const IGNORED_TARGET_URL_MARKERS = [ 'initialRoute=%2Favatar-overlay', @@ -10408,20 +10452,20 @@ var __webpack_modules__ = { ]; } function durableThreadKey(threadId) { - if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + if ((0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) return threadId; try { - return (0, _codex_thread_id_js__rspack_import_0.SX)(threadId); + return (0, _codex_thread_id_js__rspack_import_1.SX)(threadId); } catch { return threadId.startsWith("local:") ? threadId.slice("local:".length) || threadId : threadId; } } function toDesktopForm(threadId) { - if (!threadId || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + if (!threadId || (0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) return threadId; if (threadId.startsWith("local:")) return threadId; return `${"local:"}${threadId}`; } function preferThreadRow(left, right) { - const score = (row)=>(row.selected ? 4 : 0) + (row.pinned ? 2 : 0) + (row.threadId.startsWith("local:") && !(0, _codex_thread_id_js__rspack_import_0.vr)(row.threadId) ? 1 : 0); + const score = (row)=>(row.selected ? 4 : 0) + (row.pinned ? 2 : 0) + (row.threadId.startsWith("local:") && !(0, _codex_thread_id_js__rspack_import_1.vr)(row.threadId) ? 1 : 0); return score(right) > score(left) ? right : left; } const LIST_THREADS_EXPRESSION = `(() => { @@ -10659,7 +10703,7 @@ var __webpack_modules__ = { async function openThreadInDom(session, sessionId, threadId) { const current = await readConversationIdFromDom(session, sessionId); if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; - if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + if ((0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { limit: 200 }); @@ -10669,7 +10713,7 @@ var __webpack_modules__ = { sessionId }); if (!result?.ok) { - if (result?.error === 'thread-not-found' && !(0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + if (result?.error === 'thread-not-found' && !(0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) { const navigated = await session.evaluate(navigateToThreadExpression(threadId), { sessionId }); @@ -10689,7 +10733,7 @@ var __webpack_modules__ = { }) === true) { archivedSince ??= Date.now(); if (Date.now() - archivedSince >= 500) { - throw new Error(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived; unarchive it in Desktop before opening`); + throw new _errors_js__rspack_import_0.fw(threadId); } } else { archivedSince = null; @@ -10702,12 +10746,12 @@ var __webpack_modules__ = { const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; lastConversationId = current; if (!threadId) return; - if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { limit: 200 }); const selected = rows.find((row)=>row.selected); - if (!current && (!selected || (0, _codex_thread_id_js__rspack_import_0.vr)(selected.threadId))) return; + if (!current && (!selected || (0, _codex_thread_id_js__rspack_import_1.vr)(selected.threadId))) return; } else if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; } await delay(250); @@ -10776,6 +10820,7 @@ var __webpack_modules__ = { sessionId }); if (!focused?.ok) { + if (focused?.error === 'composer-has-draft') throw new _errors_js__rspack_import_0.oN(); throw new Error(`ChatGPT Desktop composer unavailable: ${focused?.error || 'not found'}`); } } @@ -10853,7 +10898,7 @@ var __webpack_modules__ = { const deadline = Date.now() + timeoutMs; while(Date.now() < deadline){ const id = await readConversationIdFromDom(session, sessionId); - if (id && !(0, _codex_thread_id_js__rspack_import_0.vr)(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { + if (id && !(0, _codex_thread_id_js__rspack_import_1.vr)(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { return id; } await delay(200); @@ -10861,10 +10906,10 @@ var __webpack_modules__ = { throw new Error(`ChatGPT Desktop conversation id did not appear on [data-response-annotation-conversation] within ${timeoutMs}ms`); } function resolveDurableThreadId(conversationId, fallbackThreadId) { - if (conversationId && !(0, _codex_thread_id_js__rspack_import_0.vr)(conversationId)) { + if (conversationId && !(0, _codex_thread_id_js__rspack_import_1.vr)(conversationId)) { return toDesktopForm(conversationId); } - if (fallbackThreadId && !(0, _codex_thread_id_js__rspack_import_0.vr)(fallbackThreadId) && fallbackThreadId !== 'new') { + if (fallbackThreadId && !(0, _codex_thread_id_js__rspack_import_1.vr)(fallbackThreadId) && fallbackThreadId !== 'new') { return toDesktopForm(fallbackThreadId); } return null; @@ -11173,6 +11218,26 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); + class ArchivedThreadError extends Error { + code = 'ARCHIVED_THREAD'; + reason = 'archived-thread'; + delivery = 'rejected'; + threadId; + constructor(threadId){ + super(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived. Read it through app-server, or pass unarchive: true on send to unarchive before sending.`); + this.name = 'ArchivedThreadError'; + this.threadId = threadId; + } + } + class ComposerDraftError extends Error { + code = 'COMPOSER_HAS_DRAFT'; + reason = 'composer-has-draft'; + delivery = 'rejected'; + constructor(){ + super('ChatGPT Desktop composer contains an unsent draft; inspect it in Desktop before sending.'); + this.name = 'ComposerDraftError'; + } + } class NotImplementedError extends Error { code = 'NOT_IMPLEMENTED'; delivery = 'rejected'; @@ -11204,6 +11269,8 @@ var __webpack_modules__ = { EH: ()=>NotImplementedError, Rg: ()=>_codex_remote_control_js__rspack_import_0.Rg, c$: ()=>CdpHostRejectedError, + fw: ()=>ArchivedThreadError, + oN: ()=>ComposerDraftError, sO: ()=>CdpUnreachableError }); }, @@ -11218,6 +11285,7 @@ var __webpack_modules__ = { listThreads: _app_server_fallback_js__rspack_import_1.OI, searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, + unarchiveThread: _app_server_fallback_js__rspack_import_1.qL, statusProbe: _app_server_fallback_js__rspack_import_1.dM, listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, listHosts: _remote_threads_js__rspack_import_4.Kl, @@ -11286,6 +11354,7 @@ var __webpack_modules__ = { limit: 10000, host, modelProvider: options.modelProvider, + project: options.project, remotes }); const offset = remoteOffset ?? 0; @@ -11306,7 +11375,7 @@ var __webpack_modules__ = { } } const remoteKeys = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); - const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; + const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); let appList = null; let appError; @@ -11335,6 +11404,7 @@ var __webpack_modules__ = { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes }); @@ -11472,7 +11542,8 @@ var __webpack_modules__ = { const appList = await this.#fallbacks.searchThreads({ query: options.query, limit, - modelProviders + modelProviders, + project: options.project }); const cdpList = await this.#tryCdpList({ limit @@ -11482,6 +11553,7 @@ var __webpack_modules__ = { limit: 10000, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, remotes: this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); @@ -11494,6 +11566,7 @@ var __webpack_modules__ = { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes: [] }); @@ -11517,6 +11590,7 @@ var __webpack_modules__ = { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) }); @@ -11564,14 +11638,29 @@ var __webpack_modules__ = { } } async sendMessage(options) { + if (options.threadId) { + const remote = (0, _remote_threads_js__rspack_import_4.KI)(options.threadId); + if (remote) throw new _errors_js__rspack_import_2.Rg(options.threadId, remote.hostId, remote.hostName); + } await this.#ensureCdp(); - return this.#cdp.sendMessage(options); + try { + return await this.#cdp.sendMessage(options); + } catch (error) { + if (!(error instanceof _errors_js__rspack_import_2.fw) || !options.unarchive || !options.threadId) throw error; + await (this.#fallbacks.unarchiveThread ?? _app_server_fallback_js__rspack_import_1.qL)(options.threadId); + return this.#cdp.sendMessage({ + ...options, + unarchive: false + }); + } } async waitForReply(options) { await this.#ensureCdp(); return this.#cdp.waitForReply(options); } async openThread(threadId, options) { + const remote = (0, _remote_threads_js__rspack_import_4.KI)(threadId); + if (remote) throw new _errors_js__rspack_import_2.Rg(threadId, remote.hostId, remote.hostName); await this.#ensureCdp(); return this.#cdp.openThread(threadId, options); } @@ -11679,7 +11768,7 @@ var __webpack_modules__ = { threads: merged }; } - function finalizeThreadList(base, { limit, host = 'all', modelProvider, groupBy, remotes }) { + function finalizeThreadList(base, { limit, host = 'all', modelProvider, project, groupBy, remotes }) { const remoteById = new Map(remotes.map((thread)=>[ (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId, thread @@ -11720,6 +11809,7 @@ var __webpack_modules__ = { const filtered = merged.filter((thread)=>{ if (!hostMatches(thread, host)) return false; if (!modelProviderMatches(thread, modelProvider)) return false; + if (!projectMatches(thread, project)) return false; return true; }); const limited = filtered.slice(0, limit); @@ -11736,6 +11826,9 @@ var __webpack_modules__ = { host, ...modelProvider ? { modelProvider + } : {}, + ...project ? { + project } : {} }; if (groupBy === 'host') { @@ -11794,6 +11887,14 @@ var __webpack_modules__ = { if (!modelProvider) return true; return thread.modelProvider === modelProvider; } + function projectMatches(thread, project) { + if (!project) return true; + const needle = project.trim().toLowerCase(); + return [ + thread.project, + thread.projectId + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } function threadMatchesQuery(thread, needle) { if (!needle) return true; return [ @@ -12317,6 +12418,7 @@ var __webpack_modules__ = { cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), + project: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const searchThreadsSchema = zod__rspack_import_4.Ikc({ @@ -12325,6 +12427,7 @@ var __webpack_modules__ = { limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), + project: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const listHostsSchema = zod__rspack_import_4.Ikc({ @@ -12337,13 +12440,29 @@ var __webpack_modules__ = { full: zod__rspack_import_4.zMY().default(false), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); + const openThreadSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId, + openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) + }).strict(); const sendSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), text: zod__rspack_import_4.YjP().trim().min(1).max(100000), project: zod__rspack_import_4.YjP().min(1).max(256).optional(), + unarchive: zod__rspack_import_4.zMY().default(false), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) - }).strict(); + }).strict().refine((value)=>!value.unarchive || Boolean(value.threadId), { + message: 'unarchive requires an existing threadId', + path: [ + 'unarchive' + ] + }).refine((value)=>!value.threadId || !value.project, { + message: 'project is only for a new thread; omit threadId', + path: [ + 'project' + ] + }); const waitReplySchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), @@ -12428,6 +12547,7 @@ var __webpack_modules__ = { cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, + project: input.project, groupBy: input.groupBy })); return asResult({ @@ -12449,6 +12569,7 @@ var __webpack_modules__ = { limit: input.limit, host: input.host, modelProvider: input.modelProvider, + project: input.project, groupBy: input.groupBy }); }); @@ -12492,6 +12613,19 @@ var __webpack_modules__ = { return mapError(error); } } + async function openThreadOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.openThread(input.threadId, { + openTimeoutMs: input.openTimeoutMs + })); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } async function sendOperation(input) { try { input = sendSchema.parse(input); @@ -12499,6 +12633,7 @@ var __webpack_modules__ = { threadId: input.threadId, text: input.text, project: input.project, + unarchive: input.unarchive, openTimeoutMs: input.openTimeoutMs })); return asResult({ @@ -40987,6 +41122,14 @@ var __webpack_modules__ = { "repeated": false, "required": false }, + { + "description": "Project label or projectId filter.", + "key": "project", + "kind": "string", + "option": "project", + "repeated": false, + "required": false + }, { "key": "query", "kind": "string", @@ -41043,6 +41186,14 @@ var __webpack_modules__ = { "option": "thread-id", "repeated": false, "required": false + }, + { + "description": "Explicitly unarchive an existing archived thread before sending.", + "key": "unarchive", + "kind": "boolean", + "option": "unarchive", + "repeated": false, + "required": false } ], "path": [ @@ -41132,6 +41283,14 @@ var __webpack_modules__ = { "option": "port", "repeated": false, "required": false + }, + { + "description": "Project label or projectId filter.", + "key": "project", + "kind": "string", + "option": "project", + "repeated": false, + "required": false } ], "path": [ diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index acf0247..f84adbf 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8103,7 +8103,7 @@ var __webpack_modules__ = { modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } - async function appServerSearchThreads({ query, limit = 50, modelProviders = [] }) { + async function appServerSearchThreads({ query, limit = 50, modelProviders = [], project }) { const needle = query.trim().toLowerCase(); if (!needle) { return appServerListThreads({ @@ -8122,7 +8122,10 @@ var __webpack_modules__ = { }); for (const thread of out.threads){ const mapped = mapListedThread(thread); - if (threadMatchesQuery(mapped, needle)) matched.push(mapped); + if (threadMatchesQuery(mapped, needle) && (!project || [ + mapped.project, + mapped.projectId + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase())))) matched.push(mapped); if (matched.length >= limit) break; } if (out.nextCursor == null || typeof out.nextCursor !== 'string') { @@ -8203,6 +8206,20 @@ var __webpack_modules__ = { throw maybeRemoteThreadError(error, bare); } } + async function appServerUnarchiveThread(threadId) { + const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + const result = await client.request('thread/unarchive', { + threadId: bare + }); + if (!result || typeof result !== 'object' || !('thread' in result) || !result.thread || typeof result.thread !== 'object' || !('id' in result.thread) || result.thread.id !== bare) { + throw new Error(`thread/unarchive returned no thread for ${bare}`); + } + } finally{ + client.close(); + } + } async function readLocalThread(bare, { limit, full }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { @@ -8475,7 +8492,8 @@ var __webpack_modules__ = { OI: ()=>appServerListThreads, X: ()=>discoverModelProviders, aI: ()=>appServerSearchThreads, - dM: ()=>appServerStatusProbe + dM: ()=>appServerStatusProbe, + qL: ()=>appServerUnarchiveThread }); }, "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -8632,7 +8650,16 @@ var __webpack_modules__ = { } async openThread(threadId, { openTimeoutMs = 90000 } = {}) { const sessionId = await this.#ensurePageSession(); - await this.#openAndWait(sessionId, threadId, openTimeoutMs); + try { + await this.#openAndWait(sessionId, threadId, openTimeoutMs); + } catch (error) { + if (error instanceof _errors_js__rspack_import_0.fw) return { + threadId, + backend: 'cdp', + archived: true + }; + throw error; + } return { threadId, backend: 'cdp' @@ -8720,7 +8747,8 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var _codex_thread_id_js__rspack_import_0 = __webpack_require__("./src/core/codex/thread-id.js"); + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _codex_thread_id_js__rspack_import_1 = __webpack_require__("./src/core/codex/thread-id.js"); const MAIN_WINDOW_URL = 'app://-/index.html'; const IGNORED_TARGET_URL_MARKERS = [ 'initialRoute=%2Favatar-overlay', @@ -8810,20 +8838,20 @@ var __webpack_modules__ = { ]; } function durableThreadKey(threadId) { - if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + if ((0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) return threadId; try { - return (0, _codex_thread_id_js__rspack_import_0.SX)(threadId); + return (0, _codex_thread_id_js__rspack_import_1.SX)(threadId); } catch { return threadId.startsWith("local:") ? threadId.slice("local:".length) || threadId : threadId; } } function toDesktopForm(threadId) { - if (!threadId || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + if (!threadId || (0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) return threadId; if (threadId.startsWith("local:")) return threadId; return `${"local:"}${threadId}`; } function preferThreadRow(left, right) { - const score = (row)=>(row.selected ? 4 : 0) + (row.pinned ? 2 : 0) + (row.threadId.startsWith("local:") && !(0, _codex_thread_id_js__rspack_import_0.vr)(row.threadId) ? 1 : 0); + const score = (row)=>(row.selected ? 4 : 0) + (row.pinned ? 2 : 0) + (row.threadId.startsWith("local:") && !(0, _codex_thread_id_js__rspack_import_1.vr)(row.threadId) ? 1 : 0); return score(right) > score(left) ? right : left; } const LIST_THREADS_EXPRESSION = `(() => { @@ -9061,7 +9089,7 @@ var __webpack_modules__ = { async function openThreadInDom(session, sessionId, threadId) { const current = await readConversationIdFromDom(session, sessionId); if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; - if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + if ((0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { limit: 200 }); @@ -9071,7 +9099,7 @@ var __webpack_modules__ = { sessionId }); if (!result?.ok) { - if (result?.error === 'thread-not-found' && !(0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + if (result?.error === 'thread-not-found' && !(0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) { const navigated = await session.evaluate(navigateToThreadExpression(threadId), { sessionId }); @@ -9091,7 +9119,7 @@ var __webpack_modules__ = { }) === true) { archivedSince ??= Date.now(); if (Date.now() - archivedSince >= 500) { - throw new Error(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived; unarchive it in Desktop before opening`); + throw new _errors_js__rspack_import_0.fw(threadId); } } else { archivedSince = null; @@ -9104,12 +9132,12 @@ var __webpack_modules__ = { const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; lastConversationId = current; if (!threadId) return; - if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { limit: 200 }); const selected = rows.find((row)=>row.selected); - if (!current && (!selected || (0, _codex_thread_id_js__rspack_import_0.vr)(selected.threadId))) return; + if (!current && (!selected || (0, _codex_thread_id_js__rspack_import_1.vr)(selected.threadId))) return; } else if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; } await delay(250); @@ -9178,6 +9206,7 @@ var __webpack_modules__ = { sessionId }); if (!focused?.ok) { + if (focused?.error === 'composer-has-draft') throw new _errors_js__rspack_import_0.oN(); throw new Error(`ChatGPT Desktop composer unavailable: ${focused?.error || 'not found'}`); } } @@ -9255,7 +9284,7 @@ var __webpack_modules__ = { const deadline = Date.now() + timeoutMs; while(Date.now() < deadline){ const id = await readConversationIdFromDom(session, sessionId); - if (id && !(0, _codex_thread_id_js__rspack_import_0.vr)(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { + if (id && !(0, _codex_thread_id_js__rspack_import_1.vr)(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { return id; } await delay(200); @@ -9263,10 +9292,10 @@ var __webpack_modules__ = { throw new Error(`ChatGPT Desktop conversation id did not appear on [data-response-annotation-conversation] within ${timeoutMs}ms`); } function resolveDurableThreadId(conversationId, fallbackThreadId) { - if (conversationId && !(0, _codex_thread_id_js__rspack_import_0.vr)(conversationId)) { + if (conversationId && !(0, _codex_thread_id_js__rspack_import_1.vr)(conversationId)) { return toDesktopForm(conversationId); } - if (fallbackThreadId && !(0, _codex_thread_id_js__rspack_import_0.vr)(fallbackThreadId) && fallbackThreadId !== 'new') { + if (fallbackThreadId && !(0, _codex_thread_id_js__rspack_import_1.vr)(fallbackThreadId) && fallbackThreadId !== 'new') { return toDesktopForm(fallbackThreadId); } return null; @@ -9575,6 +9604,26 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); + class ArchivedThreadError extends Error { + code = 'ARCHIVED_THREAD'; + reason = 'archived-thread'; + delivery = 'rejected'; + threadId; + constructor(threadId){ + super(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived. Read it through app-server, or pass unarchive: true on send to unarchive before sending.`); + this.name = 'ArchivedThreadError'; + this.threadId = threadId; + } + } + class ComposerDraftError extends Error { + code = 'COMPOSER_HAS_DRAFT'; + reason = 'composer-has-draft'; + delivery = 'rejected'; + constructor(){ + super('ChatGPT Desktop composer contains an unsent draft; inspect it in Desktop before sending.'); + this.name = 'ComposerDraftError'; + } + } class NotImplementedError extends Error { code = 'NOT_IMPLEMENTED'; delivery = 'rejected'; @@ -9606,6 +9655,8 @@ var __webpack_modules__ = { EH: ()=>NotImplementedError, Rg: ()=>_codex_remote_control_js__rspack_import_0.Rg, c$: ()=>CdpHostRejectedError, + fw: ()=>ArchivedThreadError, + oN: ()=>ComposerDraftError, sO: ()=>CdpUnreachableError }); }, @@ -9620,6 +9671,7 @@ var __webpack_modules__ = { listThreads: _app_server_fallback_js__rspack_import_1.OI, searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, + unarchiveThread: _app_server_fallback_js__rspack_import_1.qL, statusProbe: _app_server_fallback_js__rspack_import_1.dM, listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, listHosts: _remote_threads_js__rspack_import_4.Kl, @@ -9688,6 +9740,7 @@ var __webpack_modules__ = { limit: 10000, host, modelProvider: options.modelProvider, + project: options.project, remotes }); const offset = remoteOffset ?? 0; @@ -9708,7 +9761,7 @@ var __webpack_modules__ = { } } const remoteKeys = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); - const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; + const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); let appList = null; let appError; @@ -9737,6 +9790,7 @@ var __webpack_modules__ = { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes }); @@ -9874,7 +9928,8 @@ var __webpack_modules__ = { const appList = await this.#fallbacks.searchThreads({ query: options.query, limit, - modelProviders + modelProviders, + project: options.project }); const cdpList = await this.#tryCdpList({ limit @@ -9884,6 +9939,7 @@ var __webpack_modules__ = { limit: 10000, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, remotes: this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); @@ -9896,6 +9952,7 @@ var __webpack_modules__ = { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes: [] }); @@ -9919,6 +9976,7 @@ var __webpack_modules__ = { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) }); @@ -9966,14 +10024,29 @@ var __webpack_modules__ = { } } async sendMessage(options) { + if (options.threadId) { + const remote = (0, _remote_threads_js__rspack_import_4.KI)(options.threadId); + if (remote) throw new _errors_js__rspack_import_2.Rg(options.threadId, remote.hostId, remote.hostName); + } await this.#ensureCdp(); - return this.#cdp.sendMessage(options); + try { + return await this.#cdp.sendMessage(options); + } catch (error) { + if (!(error instanceof _errors_js__rspack_import_2.fw) || !options.unarchive || !options.threadId) throw error; + await (this.#fallbacks.unarchiveThread ?? _app_server_fallback_js__rspack_import_1.qL)(options.threadId); + return this.#cdp.sendMessage({ + ...options, + unarchive: false + }); + } } async waitForReply(options) { await this.#ensureCdp(); return this.#cdp.waitForReply(options); } async openThread(threadId, options) { + const remote = (0, _remote_threads_js__rspack_import_4.KI)(threadId); + if (remote) throw new _errors_js__rspack_import_2.Rg(threadId, remote.hostId, remote.hostName); await this.#ensureCdp(); return this.#cdp.openThread(threadId, options); } @@ -10081,7 +10154,7 @@ var __webpack_modules__ = { threads: merged }; } - function finalizeThreadList(base, { limit, host = 'all', modelProvider, groupBy, remotes }) { + function finalizeThreadList(base, { limit, host = 'all', modelProvider, project, groupBy, remotes }) { const remoteById = new Map(remotes.map((thread)=>[ (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId, thread @@ -10122,6 +10195,7 @@ var __webpack_modules__ = { const filtered = merged.filter((thread)=>{ if (!hostMatches(thread, host)) return false; if (!modelProviderMatches(thread, modelProvider)) return false; + if (!projectMatches(thread, project)) return false; return true; }); const limited = filtered.slice(0, limit); @@ -10138,6 +10212,9 @@ var __webpack_modules__ = { host, ...modelProvider ? { modelProvider + } : {}, + ...project ? { + project } : {} }; if (groupBy === 'host') { @@ -10196,6 +10273,14 @@ var __webpack_modules__ = { if (!modelProvider) return true; return thread.modelProvider === modelProvider; } + function projectMatches(thread, project) { + if (!project) return true; + const needle = project.trim().toLowerCase(); + return [ + thread.project, + thread.projectId + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } function threadMatchesQuery(thread, needle) { if (!needle) return true; return [ @@ -10719,6 +10804,7 @@ var __webpack_modules__ = { cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), + project: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const searchThreadsSchema = zod__rspack_import_4.Ikc({ @@ -10727,6 +10813,7 @@ var __webpack_modules__ = { limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), + project: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const listHostsSchema = zod__rspack_import_4.Ikc({ @@ -10739,13 +10826,29 @@ var __webpack_modules__ = { full: zod__rspack_import_4.zMY().default(false), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); + const openThreadSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId, + openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) + }).strict(); const sendSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), text: zod__rspack_import_4.YjP().trim().min(1).max(100000), project: zod__rspack_import_4.YjP().min(1).max(256).optional(), + unarchive: zod__rspack_import_4.zMY().default(false), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) - }).strict(); + }).strict().refine((value)=>!value.unarchive || Boolean(value.threadId), { + message: 'unarchive requires an existing threadId', + path: [ + 'unarchive' + ] + }).refine((value)=>!value.threadId || !value.project, { + message: 'project is only for a new thread; omit threadId', + path: [ + 'project' + ] + }); const waitReplySchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), @@ -10830,6 +10933,7 @@ var __webpack_modules__ = { cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, + project: input.project, groupBy: input.groupBy })); return asResult({ @@ -10851,6 +10955,7 @@ var __webpack_modules__ = { limit: input.limit, host: input.host, modelProvider: input.modelProvider, + project: input.project, groupBy: input.groupBy }); }); @@ -10894,6 +10999,19 @@ var __webpack_modules__ = { return mapError(error); } } + async function openThreadOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.openThread(input.threadId, { + openTimeoutMs: input.openTimeoutMs + })); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } async function sendOperation(input) { try { input = sendSchema.parse(input); @@ -10901,6 +11019,7 @@ var __webpack_modules__ = { threadId: input.threadId, text: input.text, project: input.project, + unarchive: input.unarchive, openTimeoutMs: input.openTimeoutMs })); return asResult({ @@ -10959,6 +11078,7 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Bm: ()=>listHostsOperation, D6: ()=>resultText, + Iu: ()=>openThreadOperation, UK: ()=>readThreadOperation, UP: ()=>sendOperation, Uj: ()=>statusOperation, @@ -10969,6 +11089,7 @@ var __webpack_modules__ = { FC: listThreadsSchema, FD: resultSchema, Fn: waitReplySchema, + OR: openThreadSchema, Rf: listHostsSchema, Wi: sendSchema, aW: statusSchema, @@ -11613,7 +11734,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list hosts', - description: 'Discover local, remote-control, and managed SSH hosts from Desktop state, including nested remote-thread summaries. Host names are null when Desktop has no display name. Providers come from paged app-server inventory and remote summaries. Result includes sources and discovery warnings.', + description: 'Discover local, remote-control environment ids, managed SSH hosts, and modelProvider ids. hostName is null when Desktop has no real display name. Use hostId or label in list/search filters; remote thread ids must be read on the owning host. warnings report provider discovery failures.', annotations: { readOnlyHint: true }, @@ -11652,7 +11773,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'Page ChatGPT Desktop / Codex threads with cursor and nextCursor. Merges local app-server rows, CDP sidebar rows, and nested remote-control summaries. Discover dynamic host and modelProvider filters via chatgpt_desktop_list_hosts. Optional groupBy=host. Result reports the contributing backends and warnings.', + description: 'List Desktop threads, then pass nextCursor as cursor until null. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', annotations: { readOnlyHint: true }, @@ -11667,11 +11788,12 @@ var __webpack_modules__ = { }, limit: { type: 'number', - description: 'Maximum threads (1-200).' + default: 50, + description: 'Maximum threads per page.' }, cursor: { type: 'string', - description: 'Opaque nextCursor from a previous page.' + description: 'Opaque nextCursor from the prior page; keep filters unchanged.' }, host: { type: 'string', @@ -11681,6 +11803,10 @@ var __webpack_modules__ = { type: 'string', description: 'Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.' }, + project: { + type: 'string', + description: 'Match a Desktop project label or app-server projectId. Dynamic string, not an enum.' + }, groupBy: { type: 'string', enum: [ @@ -11706,6 +11832,56 @@ var __webpack_modules__ = { "default": __rspack_default_export }); }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop open thread', + description: 'Navigate Desktop to an existing local: or bare conversation id, even when the row is absent from the sidebar. Archived routes return archived:true without unarchiving; read them with chatgpt_desktop_read_thread. A remote-control id is owned by its hostId and cannot be opened on this Mac. CDP_UNREACHABLE means Desktop must be reachable locally.', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.OR, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number', + description: 'Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).' + }, + threadId: { + type: 'string', + description: 'local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.' + }, + openTimeoutMs: { + type: 'number', + description: 'Maximum time to wait for the requested conversation (1-600000 ms).' + } + }, + required: [ + 'threadId' + ] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.Iu)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.OR + }, { + "default": __rspack_default_export + }); + }, "./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.react-server.js"); @@ -11714,7 +11890,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Read paged ChatGPT Desktop turns through app-server, including userText, assistantText, and completedAt as endedAt. Remote-only threads return REMOTE_THREAD_NOT_LOADED with hostId. CDP fallback reports complete:false and a warning when app-server fails. Result includes backend.', + description: 'Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Recent defaults to 100 turns; full pages up to 2000 from the start. Archived threads remain readable. complete:false means partial history; warnings preserve app-server/frame errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.', annotations: { readOnlyHint: true }, @@ -11732,7 +11908,7 @@ var __webpack_modules__ = { }, threadId: { type: 'string', - description: 'Desktop sidebar id (local:) or bare app-server thread id.' + description: 'local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.' }, limit: { type: 'number' @@ -11773,7 +11949,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop search threads', - description: 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.', + description: 'Search Desktop thread metadata by case-insensitive substring. Dynamic hostId/hostName, modelProvider, and project filters apply. Search scans bounded app-server pages and reports warnings if incomplete; use list_threads cursor for exhaustive paging. Remote results identify hostId and cannot be read on this Mac.', annotations: { readOnlyHint: true }, @@ -11792,7 +11968,8 @@ var __webpack_modules__ = { }, limit: { type: 'number', - description: 'Maximum matches (1-200).' + default: 50, + description: 'Maximum matches.' }, host: { type: 'string', @@ -11802,6 +11979,10 @@ var __webpack_modules__ = { type: 'string', description: 'Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.' }, + project: { + type: 'string', + description: 'Match a Desktop project label or app-server projectId.' + }, groupBy: { type: 'string', enum: [ @@ -11837,7 +12018,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop send', - description: 'Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.', + description: 'Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.', annotations: { readOnlyHint: false }, @@ -11855,14 +12036,19 @@ var __webpack_modules__ = { }, threadId: { type: 'string', - description: 'Sidebar thread id; omit to start a new chat.' + description: 'local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.' }, text: { type: 'string' }, project: { type: 'string', - description: 'Preferred project for new chats (Start new chat in ).' + description: 'With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.' + }, + unarchive: { + type: 'boolean', + default: false, + description: 'Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.' }, openTimeoutMs: { type: 'number' @@ -11895,7 +12081,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop status', - description: 'Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.', + description: 'Check local ChatGPT Desktop CDP before send, wait, or open. reachable:false and exitCode:1 mean CDP is down even if appServerFallback.reachable is true; list/search/read may still work through app-server. There is no remote CDP transport.', annotations: { readOnlyHint: true }, @@ -11935,7 +12121,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop wait for reply', - description: 'Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.', + description: 'After chatgpt_desktop_send, wait for the selected Desktop reply over CDP. Accept the returned durable local: or the temporary local:client-new-thread:* while selected; omit threadId only when staying on the same selected chat. Returns reply, durable threadId and conversationId. timeout is not proof the send failed; CDP_UNREACHABLE requires Desktop recovery. Remote ids must be handled on their hostId.', annotations: { readOnlyHint: true }, @@ -11952,10 +12138,12 @@ var __webpack_modules__ = { type: 'number' }, threadId: { - type: 'string' + type: 'string', + description: 'Durable local:, bare id, or selected local:client-new-thread:* from send.' }, timeoutMs: { - type: 'number' + type: 'number', + default: 120000 } }, required: [] @@ -27966,51 +28154,53 @@ function __webpack_require__(moduleId) { var __webpack_exports__ = {}; var node_worker_threads__rspack_import_0 = __webpack_require__("node:worker_threads"); var react__rspack_import_1 = __webpack_require__("./node_modules/react/react.react-server.js"); -var _agent_bundle_runtime_flight_server__rspack_import_26 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); -var _agent_bundle_runtime__rspack_import_23 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); -var _agent_bundle_runtime__rspack_import_24 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); -var _agent_bundle_runtime__rspack_import_25 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); +var _agent_bundle_runtime_flight_server__rspack_import_27 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/flight/server.js"); +var _agent_bundle_runtime__rspack_import_24 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); +var _agent_bundle_runtime__rspack_import_25 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/736.js"); +var _agent_bundle_runtime__rspack_import_26 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); var node_url__rspack_import_2 = __webpack_require__("node:url"); var _src_mcp_grok_bot_tools_chatgpt_desktop_list_hosts_tsx__rspack_import_3 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"); var _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_4 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); -var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); -var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); -var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); -var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); -var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); -var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); -var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); -var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); -var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); -var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); -var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); -var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); -var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_21 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); -var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_22 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_open_thread_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); +var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); +var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); +var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); +var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); +var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); +var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); +var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); +var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); +var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); +var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); +var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); +var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_21 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); +var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_22 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); +var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_23 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); const route0 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_hosts_tsx__rspack_import_3, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_hosts_tsx__rspack_import_3); const route1 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_4, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_4); -const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_5); -const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_6); -const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_7); -const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_8); -const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_9); -const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_10); -const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_11); -const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_12); -const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_13); -const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_14); -const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_15); -const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_16); -const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_17); -const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_18); -const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_19); -const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_20); -const route18 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_21, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_21); -const route19 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_22, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_22); +const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_open_thread_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_open_thread_tsx__rspack_import_5); +const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_6); +const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_7); +const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_8); +const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_9); +const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_10); +const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_11); +const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_12); +const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_13); +const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_14); +const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_15); +const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_16); +const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_17); +const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_18); +const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_19); +const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_20); +const route18 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_21, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_21); +const route19 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_22, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_22); +const route20 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_23, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_23); globalThis.__rspack_rsc_manifest__ ??= Object.freeze({ clientManifest: Object.freeze({}) }); @@ -28022,7 +28212,7 @@ const processLifetime = { instanceId: crypto.randomUUID(), pid: process.pid }; -const pluginRoot = (0, _agent_bundle_runtime__rspack_import_23.E7)({ +const pluginRoot = (0, _agent_bundle_runtime__rspack_import_24.E7)({ fallback: (0, node_url__rspack_import_2.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); @@ -28033,7 +28223,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Discover local, remote-control, and managed SSH hosts from Desktop state, including nested remote-thread summaries. Host names are null when Desktop has no display name. Providers come from paged app-server inventory and remote summaries. Result includes sources and discovery warnings.", + "description": "Discover local, remote-control environment ids, managed SSH hosts, and modelProvider ids. hostName is null when Desktop has no real display name. Use hostId or label in list/search filters; remote thread ids must be read on the owning host. warnings report provider discovery failures.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -28057,12 +28247,12 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Page ChatGPT Desktop / Codex threads with cursor and nextCursor. Merges local app-server rows, CDP sidebar rows, and nested remote-control summaries. Discover dynamic host and modelProvider filters via chatgpt_desktop_list_hosts. Optional groupBy=host. Result reports the contributing backends and warnings.", + "description": "List Desktop threads, then pass nextCursor as cursor until null. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.", "inputJsonSchema": { "additionalProperties": false, "properties": { "cursor": { - "description": "Opaque nextCursor from a previous page.", + "description": "Opaque nextCursor from the prior page; keep filters unchanged.", "type": "string" }, "groupBy": { @@ -28077,7 +28267,8 @@ const routes = Object.freeze({ "type": "string" }, "limit": { - "description": "Maximum threads (1-200).", + "default": 50, + "description": "Maximum threads per page.", "type": "number" }, "modelProvider": { @@ -28086,6 +28277,10 @@ const routes = Object.freeze({ }, "port": { "type": "number" + }, + "project": { + "description": "Match a Desktop project label or app-server projectId. Dynamic string, not an enum.", + "type": "string" } }, "required": [], @@ -28099,12 +28294,47 @@ const routes = Object.freeze({ name: "chatgpt_desktop_list_threads", serverId: "mcp:grok-bot" }), + "tool:grok-bot/chatgpt_desktop_open_thread": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "Navigate Desktop to an existing local: or bare conversation id, even when the row is absent from the sidebar. Archived routes return archived:true without unarchiving; read them with chatgpt_desktop_read_thread. A remote-control id is owned by its hostId and cannot be opened on this Mac. CDP_UNREACHABLE means Desktop must be reachable locally.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "openTimeoutMs": { + "description": "Maximum time to wait for the requested conversation (1-600000 ms).", + "type": "number" + }, + "port": { + "description": "Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).", + "type": "number" + }, + "threadId": { + "description": "local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.", + "type": "string" + } + }, + "required": [ + "threadId" + ], + "type": "object" + }, + "title": "ChatGPT Desktop open thread" + }, + id: "tool:grok-bot/chatgpt_desktop_open_thread", + kind: "tool", + module: route2, + name: "chatgpt_desktop_open_thread", + serverId: "mcp:grok-bot" + }), "tool:grok-bot/chatgpt_desktop_read_thread": Object.freeze({ config: { "annotations": { "readOnlyHint": true }, - "description": "Read paged ChatGPT Desktop turns through app-server, including userText, assistantText, and completedAt as endedAt. Remote-only threads return REMOTE_THREAD_NOT_LOADED with hostId. CDP fallback reports complete:false and a warning when app-server fails. Result includes backend.", + "description": "Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Recent defaults to 100 turns; full pages up to 2000 from the start. Archived threads remain readable. complete:false means partial history; warnings preserve app-server/frame errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -28123,7 +28353,7 @@ const routes = Object.freeze({ "type": "number" }, "threadId": { - "description": "Desktop sidebar id (local:) or bare app-server thread id.", + "description": "local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.", "type": "string" } }, @@ -28139,7 +28369,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_read_thread", kind: "tool", - module: route2, + module: route3, name: "chatgpt_desktop_read_thread", serverId: "mcp:grok-bot" }), @@ -28148,7 +28378,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.", + "description": "Search Desktop thread metadata by case-insensitive substring. Dynamic hostId/hostName, modelProvider, and project filters apply. Search scans bounded app-server pages and reports warnings if incomplete; use list_threads cursor for exhaustive paging. Remote results identify hostId and cannot be read on this Mac.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -28164,7 +28394,8 @@ const routes = Object.freeze({ "type": "string" }, "limit": { - "description": "Maximum matches (1-200).", + "default": 50, + "description": "Maximum matches.", "type": "number" }, "modelProvider": { @@ -28174,6 +28405,10 @@ const routes = Object.freeze({ "port": { "type": "number" }, + "project": { + "description": "Match a Desktop project label or app-server projectId.", + "type": "string" + }, "query": { "description": "Case-insensitive substring over thread metadata.", "type": "string" @@ -28188,7 +28423,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_search_threads", kind: "tool", - module: route3, + module: route4, name: "chatgpt_desktop_search_threads", serverId: "mcp:grok-bot" }), @@ -28197,7 +28432,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": false }, - "description": "Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.", + "description": "Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -28208,15 +28443,20 @@ const routes = Object.freeze({ "type": "number" }, "project": { - "description": "Preferred project for new chats (Start new chat in ).", + "description": "With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.", "type": "string" }, "text": { "type": "string" }, "threadId": { - "description": "Sidebar thread id; omit to start a new chat.", + "description": "local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.", "type": "string" + }, + "unarchive": { + "default": false, + "description": "Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.", + "type": "boolean" } }, "required": [ @@ -28231,7 +28471,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_send", kind: "tool", - module: route4, + module: route5, name: "chatgpt_desktop_send", serverId: "mcp:grok-bot" }), @@ -28240,7 +28480,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.", + "description": "Check local ChatGPT Desktop CDP before send, wait, or open. reachable:false and exitCode:1 mean CDP is down even if appServerFallback.reachable is true; list/search/read may still work through app-server. There is no remote CDP transport.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -28256,7 +28496,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_status", kind: "tool", - module: route5, + module: route6, name: "chatgpt_desktop_status", serverId: "mcp:grok-bot" }), @@ -28265,7 +28505,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.", + "description": "After chatgpt_desktop_send, wait for the selected Desktop reply over CDP. Accept the returned durable local: or the temporary local:client-new-thread:* while selected; omit threadId only when staying on the same selected chat. Returns reply, durable threadId and conversationId. timeout is not proof the send failed; CDP_UNREACHABLE requires Desktop recovery. Remote ids must be handled on their hostId.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -28273,9 +28513,11 @@ const routes = Object.freeze({ "type": "number" }, "threadId": { + "description": "Durable local:, bare id, or selected local:client-new-thread:* from send.", "type": "string" }, "timeoutMs": { + "default": 120000, "type": "number" } }, @@ -28289,7 +28531,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/chatgpt_desktop_wait_reply", kind: "tool", - module: route6, + module: route7, name: "chatgpt_desktop_wait_reply", serverId: "mcp:grok-bot" }), @@ -28325,7 +28567,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/claude_send", kind: "tool", - module: route7, + module: route8, name: "claude_send", serverId: "mcp:grok-bot" }), @@ -28406,7 +28648,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_send", kind: "tool", - module: route8, + module: route9, name: "codex_send", serverId: "mcp:grok-bot" }), @@ -28441,7 +28683,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_threads", kind: "tool", - module: route9, + module: route10, name: "codex_threads", serverId: "mcp:grok-bot" }), @@ -28491,7 +28733,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_wait", kind: "tool", - module: route10, + module: route11, name: "codex_wait", serverId: "mcp:grok-bot" }), @@ -28534,7 +28776,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/codex_watch", kind: "tool", - module: route11, + module: route12, name: "codex_watch", serverId: "mcp:grok-bot" }), @@ -28576,7 +28818,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_bridge_start", kind: "tool", - module: route12, + module: route13, name: "gbot_bridge_start", serverId: "mcp:grok-bot" }), @@ -28602,7 +28844,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_bridge_status", kind: "tool", - module: route13, + module: route14, name: "gbot_bridge_status", serverId: "mcp:grok-bot" }), @@ -28631,7 +28873,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_bridge_stop", kind: "tool", - module: route14, + module: route15, name: "gbot_bridge_stop", serverId: "mcp:grok-bot" }), @@ -28690,7 +28932,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_codex_respond", kind: "tool", - module: route15, + module: route16, name: "gbot_codex_respond", serverId: "mcp:grok-bot" }), @@ -28721,7 +28963,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_grok_approvals", kind: "tool", - module: route16, + module: route17, name: "gbot_grok_approvals", serverId: "mcp:grok-bot" }), @@ -28768,7 +29010,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_grok_respond", kind: "tool", - module: route17, + module: route18, name: "gbot_grok_respond", serverId: "mcp:grok-bot" }), @@ -28829,7 +29071,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_send", kind: "tool", - module: route18, + module: route19, name: "gbot_send", serverId: "mcp:grok-bot" }), @@ -28875,7 +29117,7 @@ const routes = Object.freeze({ }, id: "tool:grok-bot/gbot_thread", kind: "tool", - module: route19, + module: route20, name: "gbot_thread", serverId: "mcp:grok-bot" }) @@ -28923,7 +29165,7 @@ const render = async (message)=>{ }; try { const plugin = message.plugin ?? pluginRoot.identity; - await (0, _agent_bundle_runtime__rspack_import_24.iC)({ + await (0, _agent_bundle_runtime__rspack_import_25.iC)({ ...message.actor === undefined ? {} : { actor: message.actor }, @@ -28937,7 +29179,7 @@ const render = async (message)=>{ operationId: route.id, surface: route.name }, - lineage: message.lineage ?? (0, _agent_bundle_runtime__rspack_import_24.hU)('not-provided'), + lineage: message.lineage ?? (0, _agent_bundle_runtime__rspack_import_25.hU)('not-provided'), plugin, progress: { report: async (update)=>{ @@ -28953,7 +29195,7 @@ const render = async (message)=>{ session: message.session }, signal: controller.signal, - terminal: message.terminal ?? (0, _agent_bundle_runtime__rspack_import_24.hU)('not-provided'), + terminal: message.terminal ?? (0, _agent_bundle_runtime__rspack_import_25.hU)('not-provided'), ...message.workspace === undefined ? {} : { workspace: message.workspace } @@ -28988,10 +29230,10 @@ const render = async (message)=>{ type: 'observed-render-start' }); const renderStartedAt = performance.now(); - const element = validationError === undefined ? composeLayouts(observedRoute, props, controller.signal) : (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_25.g.Result, null, (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_25.g.Error, { + const element = validationError === undefined ? composeLayouts(observedRoute, props, controller.signal) : (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_26.g.Result, null, (0, react__rspack_import_1.createElement)(_agent_bundle_runtime__rspack_import_26.g.Error, { code: 'invalid-input' }, `Input validation error: ${validationError instanceof Error ? validationError.message : String(validationError)}`)); - const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_26.y)(element, { + const flight = (0, _agent_bundle_runtime_flight_server__rspack_import_27.y)(element, { signal: controller.signal }); const reader = flight.getReader(); diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index ee8200f..383c5b5 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -6511,7 +6511,7 @@ var __webpack_modules__ = { modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; } - async function appServerSearchThreads({ query, limit = 50, modelProviders = [] }) { + async function appServerSearchThreads({ query, limit = 50, modelProviders = [], project }) { const needle = query.trim().toLowerCase(); if (!needle) { return appServerListThreads({ @@ -6530,7 +6530,10 @@ var __webpack_modules__ = { }); for (const thread of out.threads){ const mapped = mapListedThread(thread); - if (threadMatchesQuery(mapped, needle)) matched.push(mapped); + if (threadMatchesQuery(mapped, needle) && (!project || [ + mapped.project, + mapped.projectId + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase())))) matched.push(mapped); if (matched.length >= limit) break; } if (out.nextCursor == null || typeof out.nextCursor !== 'string') { @@ -6611,6 +6614,20 @@ var __webpack_modules__ = { throw maybeRemoteThreadError(error, bare); } } + async function appServerUnarchiveThread(threadId) { + const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); + const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); + try { + const result = await client.request('thread/unarchive', { + threadId: bare + }); + if (!result || typeof result !== 'object' || !('thread' in result) || !result.thread || typeof result.thread !== 'object' || !('id' in result.thread) || result.thread.id !== bare) { + throw new Error(`thread/unarchive returned no thread for ${bare}`); + } + } finally{ + client.close(); + } + } async function readLocalThread(bare, { limit, full }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { @@ -6883,7 +6900,8 @@ var __webpack_modules__ = { OI: ()=>appServerListThreads, X: ()=>discoverModelProviders, aI: ()=>appServerSearchThreads, - dM: ()=>appServerStatusProbe + dM: ()=>appServerStatusProbe, + qL: ()=>appServerUnarchiveThread }); }, "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { @@ -7040,7 +7058,16 @@ var __webpack_modules__ = { } async openThread(threadId, { openTimeoutMs = 90000 } = {}) { const sessionId = await this.#ensurePageSession(); - await this.#openAndWait(sessionId, threadId, openTimeoutMs); + try { + await this.#openAndWait(sessionId, threadId, openTimeoutMs); + } catch (error) { + if (error instanceof _errors_js__rspack_import_0.fw) return { + threadId, + backend: 'cdp', + archived: true + }; + throw error; + } return { threadId, backend: 'cdp' @@ -7128,7 +7155,8 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/cdp-dom.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var _codex_thread_id_js__rspack_import_0 = __webpack_require__("./src/core/codex/thread-id.js"); + var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _codex_thread_id_js__rspack_import_1 = __webpack_require__("./src/core/codex/thread-id.js"); const MAIN_WINDOW_URL = 'app://-/index.html'; const IGNORED_TARGET_URL_MARKERS = [ 'initialRoute=%2Favatar-overlay', @@ -7218,20 +7246,20 @@ var __webpack_modules__ = { ]; } function durableThreadKey(threadId) { - if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + if ((0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) return threadId; try { - return (0, _codex_thread_id_js__rspack_import_0.SX)(threadId); + return (0, _codex_thread_id_js__rspack_import_1.SX)(threadId); } catch { return threadId.startsWith("local:") ? threadId.slice("local:".length) || threadId : threadId; } } function toDesktopForm(threadId) { - if (!threadId || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) return threadId; + if (!threadId || (0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) return threadId; if (threadId.startsWith("local:")) return threadId; return `${"local:"}${threadId}`; } function preferThreadRow(left, right) { - const score = (row)=>(row.selected ? 4 : 0) + (row.pinned ? 2 : 0) + (row.threadId.startsWith("local:") && !(0, _codex_thread_id_js__rspack_import_0.vr)(row.threadId) ? 1 : 0); + const score = (row)=>(row.selected ? 4 : 0) + (row.pinned ? 2 : 0) + (row.threadId.startsWith("local:") && !(0, _codex_thread_id_js__rspack_import_1.vr)(row.threadId) ? 1 : 0); return score(right) > score(left) ? right : left; } const LIST_THREADS_EXPRESSION = `(() => { @@ -7469,7 +7497,7 @@ var __webpack_modules__ = { async function openThreadInDom(session, sessionId, threadId) { const current = await readConversationIdFromDom(session, sessionId); if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; - if ((0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + if ((0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { limit: 200 }); @@ -7479,7 +7507,7 @@ var __webpack_modules__ = { sessionId }); if (!result?.ok) { - if (result?.error === 'thread-not-found' && !(0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + if (result?.error === 'thread-not-found' && !(0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) { const navigated = await session.evaluate(navigateToThreadExpression(threadId), { sessionId }); @@ -7499,7 +7527,7 @@ var __webpack_modules__ = { }) === true) { archivedSince ??= Date.now(); if (Date.now() - archivedSince >= 500) { - throw new Error(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived; unarchive it in Desktop before opening`); + throw new _errors_js__rspack_import_0.fw(threadId); } } else { archivedSince = null; @@ -7512,12 +7540,12 @@ var __webpack_modules__ = { const current = threadId ? await readConversationIdFromDom(session, sessionId) : ''; lastConversationId = current; if (!threadId) return; - if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_0.vr)(threadId)) { + if (threadId === 'new' || (0, _codex_thread_id_js__rspack_import_1.vr)(threadId)) { const rows = await listThreadsFromDom(session, sessionId, { limit: 200 }); const selected = rows.find((row)=>row.selected); - if (!current && (!selected || (0, _codex_thread_id_js__rspack_import_0.vr)(selected.threadId))) return; + if (!current && (!selected || (0, _codex_thread_id_js__rspack_import_1.vr)(selected.threadId))) return; } else if (current && durableThreadKey(current) === durableThreadKey(threadId)) return; } await delay(250); @@ -7586,6 +7614,7 @@ var __webpack_modules__ = { sessionId }); if (!focused?.ok) { + if (focused?.error === 'composer-has-draft') throw new _errors_js__rspack_import_0.oN(); throw new Error(`ChatGPT Desktop composer unavailable: ${focused?.error || 'not found'}`); } } @@ -7663,7 +7692,7 @@ var __webpack_modules__ = { const deadline = Date.now() + timeoutMs; while(Date.now() < deadline){ const id = await readConversationIdFromDom(session, sessionId); - if (id && !(0, _codex_thread_id_js__rspack_import_0.vr)(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { + if (id && !(0, _codex_thread_id_js__rspack_import_1.vr)(id) && !id.startsWith(TEMP_THREAD_ID_PREFIX)) { return id; } await delay(200); @@ -7671,10 +7700,10 @@ var __webpack_modules__ = { throw new Error(`ChatGPT Desktop conversation id did not appear on [data-response-annotation-conversation] within ${timeoutMs}ms`); } function resolveDurableThreadId(conversationId, fallbackThreadId) { - if (conversationId && !(0, _codex_thread_id_js__rspack_import_0.vr)(conversationId)) { + if (conversationId && !(0, _codex_thread_id_js__rspack_import_1.vr)(conversationId)) { return toDesktopForm(conversationId); } - if (fallbackThreadId && !(0, _codex_thread_id_js__rspack_import_0.vr)(fallbackThreadId) && fallbackThreadId !== 'new') { + if (fallbackThreadId && !(0, _codex_thread_id_js__rspack_import_1.vr)(fallbackThreadId) && fallbackThreadId !== 'new') { return toDesktopForm(fallbackThreadId); } return null; @@ -7983,6 +8012,26 @@ var __webpack_modules__ = { }, "./src/core/chatgpt-desktop/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); + class ArchivedThreadError extends Error { + code = 'ARCHIVED_THREAD'; + reason = 'archived-thread'; + delivery = 'rejected'; + threadId; + constructor(threadId){ + super(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived. Read it through app-server, or pass unarchive: true on send to unarchive before sending.`); + this.name = 'ArchivedThreadError'; + this.threadId = threadId; + } + } + class ComposerDraftError extends Error { + code = 'COMPOSER_HAS_DRAFT'; + reason = 'composer-has-draft'; + delivery = 'rejected'; + constructor(){ + super('ChatGPT Desktop composer contains an unsent draft; inspect it in Desktop before sending.'); + this.name = 'ComposerDraftError'; + } + } class NotImplementedError extends Error { code = 'NOT_IMPLEMENTED'; delivery = 'rejected'; @@ -8014,6 +8063,8 @@ var __webpack_modules__ = { EH: ()=>NotImplementedError, Rg: ()=>_codex_remote_control_js__rspack_import_0.Rg, c$: ()=>CdpHostRejectedError, + fw: ()=>ArchivedThreadError, + oN: ()=>ComposerDraftError, sO: ()=>CdpUnreachableError }); }, @@ -8028,6 +8079,7 @@ var __webpack_modules__ = { listThreads: _app_server_fallback_js__rspack_import_1.OI, searchThreads: _app_server_fallback_js__rspack_import_1.aI, readThread: _app_server_fallback_js__rspack_import_1.Jf, + unarchiveThread: _app_server_fallback_js__rspack_import_1.qL, statusProbe: _app_server_fallback_js__rspack_import_1.dM, listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, listHosts: _remote_threads_js__rspack_import_4.Kl, @@ -8096,6 +8148,7 @@ var __webpack_modules__ = { limit: 10000, host, modelProvider: options.modelProvider, + project: options.project, remotes }); const offset = remoteOffset ?? 0; @@ -8116,7 +8169,7 @@ var __webpack_modules__ = { } } const remoteKeys = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); - const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; + const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); let appList = null; let appError; @@ -8145,6 +8198,7 @@ var __webpack_modules__ = { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes }); @@ -8282,7 +8336,8 @@ var __webpack_modules__ = { const appList = await this.#fallbacks.searchThreads({ query: options.query, limit, - modelProviders + modelProviders, + project: options.project }); const cdpList = await this.#tryCdpList({ limit @@ -8292,6 +8347,7 @@ var __webpack_modules__ = { limit: 10000, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, remotes: this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); @@ -8304,6 +8360,7 @@ var __webpack_modules__ = { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes: [] }); @@ -8327,6 +8384,7 @@ var __webpack_modules__ = { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) }); @@ -8374,14 +8432,29 @@ var __webpack_modules__ = { } } async sendMessage(options) { + if (options.threadId) { + const remote = (0, _remote_threads_js__rspack_import_4.KI)(options.threadId); + if (remote) throw new _errors_js__rspack_import_2.Rg(options.threadId, remote.hostId, remote.hostName); + } await this.#ensureCdp(); - return this.#cdp.sendMessage(options); + try { + return await this.#cdp.sendMessage(options); + } catch (error) { + if (!(error instanceof _errors_js__rspack_import_2.fw) || !options.unarchive || !options.threadId) throw error; + await (this.#fallbacks.unarchiveThread ?? _app_server_fallback_js__rspack_import_1.qL)(options.threadId); + return this.#cdp.sendMessage({ + ...options, + unarchive: false + }); + } } async waitForReply(options) { await this.#ensureCdp(); return this.#cdp.waitForReply(options); } async openThread(threadId, options) { + const remote = (0, _remote_threads_js__rspack_import_4.KI)(threadId); + if (remote) throw new _errors_js__rspack_import_2.Rg(threadId, remote.hostId, remote.hostName); await this.#ensureCdp(); return this.#cdp.openThread(threadId, options); } @@ -8489,7 +8562,7 @@ var __webpack_modules__ = { threads: merged }; } - function finalizeThreadList(base, { limit, host = 'all', modelProvider, groupBy, remotes }) { + function finalizeThreadList(base, { limit, host = 'all', modelProvider, project, groupBy, remotes }) { const remoteById = new Map(remotes.map((thread)=>[ (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId, thread @@ -8530,6 +8603,7 @@ var __webpack_modules__ = { const filtered = merged.filter((thread)=>{ if (!hostMatches(thread, host)) return false; if (!modelProviderMatches(thread, modelProvider)) return false; + if (!projectMatches(thread, project)) return false; return true; }); const limited = filtered.slice(0, limit); @@ -8546,6 +8620,9 @@ var __webpack_modules__ = { host, ...modelProvider ? { modelProvider + } : {}, + ...project ? { + project } : {} }; if (groupBy === 'host') { @@ -8604,6 +8681,14 @@ var __webpack_modules__ = { if (!modelProvider) return true; return thread.modelProvider === modelProvider; } + function projectMatches(thread, project) { + if (!project) return true; + const needle = project.trim().toLowerCase(); + return [ + thread.project, + thread.projectId + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); + } function threadMatchesQuery(thread, needle) { if (!needle) return true; return [ @@ -9127,6 +9212,7 @@ var __webpack_modules__ = { cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), + project: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const searchThreadsSchema = zod__rspack_import_4.Ikc({ @@ -9135,6 +9221,7 @@ var __webpack_modules__ = { limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), + project: zod__rspack_import_4.YjP().min(1).max(256).optional(), groupBy: zod__rspack_import_4.euz('host').optional() }).strict(); const listHostsSchema = zod__rspack_import_4.Ikc({ @@ -9147,13 +9234,29 @@ var __webpack_modules__ = { full: zod__rspack_import_4.zMY().default(false), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); + const openThreadSchema = zod__rspack_import_4.Ikc({ + port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), + threadId, + openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) + }).strict(); const sendSchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), text: zod__rspack_import_4.YjP().trim().min(1).max(100000), project: zod__rspack_import_4.YjP().min(1).max(256).optional(), + unarchive: zod__rspack_import_4.zMY().default(false), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) - }).strict(); + }).strict().refine((value)=>!value.unarchive || Boolean(value.threadId), { + message: 'unarchive requires an existing threadId', + path: [ + 'unarchive' + ] + }).refine((value)=>!value.threadId || !value.project, { + message: 'project is only for a new thread; omit threadId', + path: [ + 'project' + ] + }); const waitReplySchema = zod__rspack_import_4.Ikc({ port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), threadId: threadId.optional(), @@ -9238,6 +9341,7 @@ var __webpack_modules__ = { cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, + project: input.project, groupBy: input.groupBy })); return asResult({ @@ -9259,6 +9363,7 @@ var __webpack_modules__ = { limit: input.limit, host: input.host, modelProvider: input.modelProvider, + project: input.project, groupBy: input.groupBy }); }); @@ -9302,6 +9407,19 @@ var __webpack_modules__ = { return mapError(error); } } + async function openThreadOperation(input) { + try { + const out = await withAdapter(input.port, (adapter)=>adapter.openThread(input.threadId, { + openTimeoutMs: input.openTimeoutMs + })); + return asResult({ + ...out, + exitCode: 0 + }); + } catch (error) { + return mapError(error); + } + } async function sendOperation(input) { try { input = sendSchema.parse(input); @@ -9309,6 +9427,7 @@ var __webpack_modules__ = { threadId: input.threadId, text: input.text, project: input.project, + unarchive: input.unarchive, openTimeoutMs: input.openTimeoutMs })); return asResult({ @@ -9367,6 +9486,7 @@ var __webpack_modules__ = { __webpack_require__.d(__webpack_exports__, { Bm: ()=>listHostsOperation, D6: ()=>resultText, + Iu: ()=>openThreadOperation, UK: ()=>readThreadOperation, UP: ()=>sendOperation, Uj: ()=>statusOperation, @@ -9377,6 +9497,7 @@ var __webpack_modules__ = { FC: listThreadsSchema, FD: resultSchema, Fn: waitReplySchema, + OR: openThreadSchema, Rf: listHostsSchema, Wi: sendSchema, aW: statusSchema, @@ -10021,7 +10142,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list hosts', - description: 'Discover local, remote-control, and managed SSH hosts from Desktop state, including nested remote-thread summaries. Host names are null when Desktop has no display name. Providers come from paged app-server inventory and remote summaries. Result includes sources and discovery warnings.', + description: 'Discover local, remote-control environment ids, managed SSH hosts, and modelProvider ids. hostName is null when Desktop has no real display name. Use hostId or label in list/search filters; remote thread ids must be read on the owning host. warnings report provider discovery failures.', annotations: { readOnlyHint: true }, @@ -10060,7 +10181,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'Page ChatGPT Desktop / Codex threads with cursor and nextCursor. Merges local app-server rows, CDP sidebar rows, and nested remote-control summaries. Discover dynamic host and modelProvider filters via chatgpt_desktop_list_hosts. Optional groupBy=host. Result reports the contributing backends and warnings.', + description: 'List Desktop threads, then pass nextCursor as cursor until null. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', annotations: { readOnlyHint: true }, @@ -10075,11 +10196,12 @@ var __webpack_modules__ = { }, limit: { type: 'number', - description: 'Maximum threads (1-200).' + default: 50, + description: 'Maximum threads per page.' }, cursor: { type: 'string', - description: 'Opaque nextCursor from a previous page.' + description: 'Opaque nextCursor from the prior page; keep filters unchanged.' }, host: { type: 'string', @@ -10089,6 +10211,10 @@ var __webpack_modules__ = { type: 'string', description: 'Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.' }, + project: { + type: 'string', + description: 'Match a Desktop project label or app-server projectId. Dynamic string, not an enum.' + }, groupBy: { type: 'string', enum: [ @@ -10114,6 +10240,56 @@ var __webpack_modules__ = { "default": __rspack_default_export }); }, + "./src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + __webpack_require__.r(__webpack_exports__); + var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); + var _agent_bundle_runtime__rspack_import_3 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/506.js"); + var agent_bundle_routes__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/routes.js"); + var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); + const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ + title: 'ChatGPT Desktop open thread', + description: 'Navigate Desktop to an existing local: or bare conversation id, even when the row is absent from the sidebar. Archived routes return archived:true without unarchiving; read them with chatgpt_desktop_read_thread. A remote-control id is owned by its hostId and cannot be opened on this Mac. CDP_UNREACHABLE means Desktop must be reachable locally.', + annotations: { + readOnlyHint: true + }, + inputSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.OR, + resultSchema: _core_chatgpt_desktop_routes_js__rspack_import_2.FD, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { + type: 'number', + description: 'Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).' + }, + threadId: { + type: 'string', + description: 'local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.' + }, + openTimeoutMs: { + type: 'number', + description: 'Maximum time to wait for the requested conversation (1-600000 ms).' + } + }, + required: [ + 'threadId' + ] + } + }, async (input)=>{ + const out = await (0, _core_chatgpt_desktop_routes_js__rspack_import_2.Iu)(input); + return (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Result, { + value: out, + children: (0, react_jsx_runtime__rspack_import_0.jsx)(_agent_bundle_runtime__rspack_import_3.g.Text, { + children: (0, _core_chatgpt_desktop_routes_js__rspack_import_2.D6)(out) + }) + }); + }); + __webpack_require__.d(__webpack_exports__, { + inputSchema: ()=>_core_chatgpt_desktop_routes_js__rspack_import_2.OR + }, { + "default": __rspack_default_export + }); + }, "./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var react_jsx_runtime__rspack_import_0 = __webpack_require__("./node_modules/react/jsx-runtime.js"); @@ -10122,7 +10298,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Read paged ChatGPT Desktop turns through app-server, including userText, assistantText, and completedAt as endedAt. Remote-only threads return REMOTE_THREAD_NOT_LOADED with hostId. CDP fallback reports complete:false and a warning when app-server fails. Result includes backend.', + description: 'Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Recent defaults to 100 turns; full pages up to 2000 from the start. Archived threads remain readable. complete:false means partial history; warnings preserve app-server/frame errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.', annotations: { readOnlyHint: true }, @@ -10140,7 +10316,7 @@ var __webpack_modules__ = { }, threadId: { type: 'string', - description: 'Desktop sidebar id (local:) or bare app-server thread id.' + description: 'local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.' }, limit: { type: 'number' @@ -10181,7 +10357,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop search threads', - description: 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.', + description: 'Search Desktop thread metadata by case-insensitive substring. Dynamic hostId/hostName, modelProvider, and project filters apply. Search scans bounded app-server pages and reports warnings if incomplete; use list_threads cursor for exhaustive paging. Remote results identify hostId and cannot be read on this Mac.', annotations: { readOnlyHint: true }, @@ -10200,7 +10376,8 @@ var __webpack_modules__ = { }, limit: { type: 'number', - description: 'Maximum matches (1-200).' + default: 50, + description: 'Maximum matches.' }, host: { type: 'string', @@ -10210,6 +10387,10 @@ var __webpack_modules__ = { type: 'string', description: 'Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.' }, + project: { + type: 'string', + description: 'Match a Desktop project label or app-server projectId.' + }, groupBy: { type: 'string', enum: [ @@ -10245,7 +10426,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop send', - description: 'Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.', + description: 'Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.', annotations: { readOnlyHint: false }, @@ -10263,14 +10444,19 @@ var __webpack_modules__ = { }, threadId: { type: 'string', - description: 'Sidebar thread id; omit to start a new chat.' + description: 'local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.' }, text: { type: 'string' }, project: { type: 'string', - description: 'Preferred project for new chats (Start new chat in ).' + description: 'With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.' + }, + unarchive: { + type: 'boolean', + default: false, + description: 'Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.' }, openTimeoutMs: { type: 'number' @@ -10303,7 +10489,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop status', - description: 'Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.', + description: 'Check local ChatGPT Desktop CDP before send, wait, or open. reachable:false and exitCode:1 mean CDP is down even if appServerFallback.reachable is true; list/search/read may still work through app-server. There is no remote CDP transport.', annotations: { readOnlyHint: true }, @@ -10343,7 +10529,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop wait for reply', - description: 'Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.', + description: 'After chatgpt_desktop_send, wait for the selected Desktop reply over CDP. Accept the returned durable local: or the temporary local:client-new-thread:* while selected; omit threadId only when staying on the same selected chat. Returns reply, durable threadId and conversationId. timeout is not proof the send failed; CDP_UNREACHABLE requires Desktop recovery. Remote ids must be handled on their hostId.', annotations: { readOnlyHint: true }, @@ -10360,10 +10546,12 @@ var __webpack_modules__ = { type: 'number' }, threadId: { - type: 'string' + type: 'string', + description: 'Durable local:, bare id, or selected local:client-new-thread:* from send.' }, timeoutMs: { - type: 'number' + type: 'number', + default: 120000 } }, required: [] @@ -59473,58 +59661,60 @@ var __webpack_modules__ = { "./.agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); var node_url__rspack_import_0 = __webpack_require__("node:url"); - var _agent_bundle_runtime__rspack_import_23 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); + var _agent_bundle_runtime__rspack_import_24 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/49.js"); var agent_bundle_mcp_server_runtime__rspack_import_1 = __webpack_require__("./node_modules/agent-bundle/dist/mcp-server-runtime.js"); - var _agent_bundle_runtime_lineage__rspack_import_24 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/lineage.js"); + var _agent_bundle_runtime_lineage__rspack_import_25 = __webpack_require__("./node_modules/@agent-bundle/runtime/dist/lineage.js"); var agent_bundle_mcp_apps__rspack_import_2 = __webpack_require__("./.agent-bundle-virtual/mcp-grok-bot-b8c2461e-0.mjs"); var _src_mcp_grok_bot_tools_chatgpt_desktop_list_hosts_tsx__rspack_import_3 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"); var _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_4 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); - var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); - var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); - var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); - var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); - var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); - var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); - var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); - var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); - var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); - var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); - var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); - var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); - var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_21 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); - var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_22 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_open_thread_tsx__rspack_import_5 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_6 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_7 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_8 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_9 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"); + var _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_10 = __webpack_require__("./src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"); + var _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_11 = __webpack_require__("./src/mcp/grok-bot/tools/claude_send.tsx"); + var _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_12 = __webpack_require__("./src/mcp/grok-bot/tools/codex_send.tsx"); + var _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_13 = __webpack_require__("./src/mcp/grok-bot/tools/codex_threads.tsx"); + var _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_14 = __webpack_require__("./src/mcp/grok-bot/tools/codex_wait.tsx"); + var _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_15 = __webpack_require__("./src/mcp/grok-bot/tools/codex_watch.tsx"); + var _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_16 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_start.tsx"); + var _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_17 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_status.tsx"); + var _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_18 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"); + var _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_19 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_codex_respond.tsx"); + var _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_20 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"); + var _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_21 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_grok_respond.tsx"); + var _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_22 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_send.tsx"); + var _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_23 = __webpack_require__("./src/mcp/grok-bot/tools/gbot_thread.tsx"); const route0 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_hosts_tsx__rspack_import_3, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_hosts_tsx__rspack_import_3); const route1 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_4, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_list_threads_tsx__rspack_import_4); - const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_5); - const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_6); - const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_7); - const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_8); - const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_9); - const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_10); - const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_11); - const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_12); - const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_13); - const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_14); - const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_15); - const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_16); - const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_17); - const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_18); - const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_19); - const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_20); - const route18 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_21, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_21); - const route19 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_22, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_22); + const route2 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_open_thread_tsx__rspack_import_5, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_open_thread_tsx__rspack_import_5); + const route3 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_6, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_read_thread_tsx__rspack_import_6); + const route4 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_7, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_search_threads_tsx__rspack_import_7); + const route5 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_8, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_send_tsx__rspack_import_8); + const route6 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_9, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_status_tsx__rspack_import_9); + const route7 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_10, 'default'), _src_mcp_grok_bot_tools_chatgpt_desktop_wait_reply_tsx__rspack_import_10); + const route8 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_11, 'default'), _src_mcp_grok_bot_tools_claude_send_tsx__rspack_import_11); + const route9 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_12, 'default'), _src_mcp_grok_bot_tools_codex_send_tsx__rspack_import_12); + const route10 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_13, 'default'), _src_mcp_grok_bot_tools_codex_threads_tsx__rspack_import_13); + const route11 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_14, 'default'), _src_mcp_grok_bot_tools_codex_wait_tsx__rspack_import_14); + const route12 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_15, 'default'), _src_mcp_grok_bot_tools_codex_watch_tsx__rspack_import_15); + const route13 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_16, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_start_tsx__rspack_import_16); + const route14 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_17, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_status_tsx__rspack_import_17); + const route15 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_18, 'default'), _src_mcp_grok_bot_tools_gbot_bridge_stop_tsx__rspack_import_18); + const route16 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_19, 'default'), _src_mcp_grok_bot_tools_gbot_codex_respond_tsx__rspack_import_19); + const route17 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_20, 'default'), _src_mcp_grok_bot_tools_gbot_grok_approvals_tsx__rspack_import_20); + const route18 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_21, 'default'), _src_mcp_grok_bot_tools_gbot_grok_respond_tsx__rspack_import_21); + const route19 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_22, 'default'), _src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_22); + const route20 = Object.assign({}, Reflect.get(_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_23, 'default'), _src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_23); const ARTIFACT_EPOCH = "gbot@0.10.1"; - const pluginRoot = (0, _agent_bundle_runtime__rspack_import_23.E7)({ + const pluginRoot = (0, _agent_bundle_runtime__rspack_import_24.E7)({ fallback: (0, node_url__rspack_import_0.fileURLToPath)(new URL('..', import.meta.url)), stateAnchor: 'user-data' }); const openLineage = async ()=>({ dispose: async ()=>undefined, - registry: (0, _agent_bundle_runtime_lineage__rspack_import_24.Q5)() + registry: (0, _agent_bundle_runtime_lineage__rspack_import_25.Q5)() }); const routes = Object.freeze({ "tool:grok-bot/chatgpt_desktop_list_hosts": Object.freeze({ @@ -59532,7 +59722,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Discover local, remote-control, and managed SSH hosts from Desktop state, including nested remote-thread summaries. Host names are null when Desktop has no display name. Providers come from paged app-server inventory and remote summaries. Result includes sources and discovery warnings.", + "description": "Discover local, remote-control environment ids, managed SSH hosts, and modelProvider ids. hostName is null when Desktop has no real display name. Use hostId or label in list/search filters; remote thread ids must be read on the owning host. warnings report provider discovery failures.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -59555,12 +59745,12 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Page ChatGPT Desktop / Codex threads with cursor and nextCursor. Merges local app-server rows, CDP sidebar rows, and nested remote-control summaries. Discover dynamic host and modelProvider filters via chatgpt_desktop_list_hosts. Optional groupBy=host. Result reports the contributing backends and warnings.", + "description": "List Desktop threads, then pass nextCursor as cursor until null. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.", "inputJsonSchema": { "additionalProperties": false, "properties": { "cursor": { - "description": "Opaque nextCursor from a previous page.", + "description": "Opaque nextCursor from the prior page; keep filters unchanged.", "type": "string" }, "groupBy": { @@ -59575,7 +59765,8 @@ var __webpack_modules__ = { "type": "string" }, "limit": { - "description": "Maximum threads (1-200).", + "default": 50, + "description": "Maximum threads per page.", "type": "number" }, "modelProvider": { @@ -59584,6 +59775,10 @@ var __webpack_modules__ = { }, "port": { "type": "number" + }, + "project": { + "description": "Match a Desktop project label or app-server projectId. Dynamic string, not an enum.", + "type": "string" } }, "required": [], @@ -59596,12 +59791,46 @@ var __webpack_modules__ = { module: route1, name: "chatgpt_desktop_list_threads" }), + "tool:grok-bot/chatgpt_desktop_open_thread": Object.freeze({ + config: { + "annotations": { + "readOnlyHint": true + }, + "description": "Navigate Desktop to an existing local: or bare conversation id, even when the row is absent from the sidebar. Archived routes return archived:true without unarchiving; read them with chatgpt_desktop_read_thread. A remote-control id is owned by its hostId and cannot be opened on this Mac. CDP_UNREACHABLE means Desktop must be reachable locally.", + "inputJsonSchema": { + "additionalProperties": false, + "properties": { + "openTimeoutMs": { + "description": "Maximum time to wait for the requested conversation (1-600000 ms).", + "type": "number" + }, + "port": { + "description": "Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).", + "type": "number" + }, + "threadId": { + "description": "local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.", + "type": "string" + } + }, + "required": [ + "threadId" + ], + "type": "object" + }, + "title": "ChatGPT Desktop open thread" + }, + id: "tool:grok-bot/chatgpt_desktop_open_thread", + kind: "tool", + module: route2, + name: "chatgpt_desktop_open_thread" + }), "tool:grok-bot/chatgpt_desktop_read_thread": Object.freeze({ config: { "annotations": { "readOnlyHint": true }, - "description": "Read paged ChatGPT Desktop turns through app-server, including userText, assistantText, and completedAt as endedAt. Remote-only threads return REMOTE_THREAD_NOT_LOADED with hostId. CDP fallback reports complete:false and a warning when app-server fails. Result includes backend.", + "description": "Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Recent defaults to 100 turns; full pages up to 2000 from the start. Archived threads remain readable. complete:false means partial history; warnings preserve app-server/frame errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -59620,7 +59849,7 @@ var __webpack_modules__ = { "type": "number" }, "threadId": { - "description": "Desktop sidebar id (local:) or bare app-server thread id.", + "description": "local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.", "type": "string" } }, @@ -59636,7 +59865,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_read_thread", kind: "tool", - module: route2, + module: route3, name: "chatgpt_desktop_read_thread" }), "tool:grok-bot/chatgpt_desktop_search_threads": Object.freeze({ @@ -59644,7 +59873,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.", + "description": "Search Desktop thread metadata by case-insensitive substring. Dynamic hostId/hostName, modelProvider, and project filters apply. Search scans bounded app-server pages and reports warnings if incomplete; use list_threads cursor for exhaustive paging. Remote results identify hostId and cannot be read on this Mac.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -59660,7 +59889,8 @@ var __webpack_modules__ = { "type": "string" }, "limit": { - "description": "Maximum matches (1-200).", + "default": 50, + "description": "Maximum matches.", "type": "number" }, "modelProvider": { @@ -59670,6 +59900,10 @@ var __webpack_modules__ = { "port": { "type": "number" }, + "project": { + "description": "Match a Desktop project label or app-server projectId.", + "type": "string" + }, "query": { "description": "Case-insensitive substring over thread metadata.", "type": "string" @@ -59684,7 +59918,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_search_threads", kind: "tool", - module: route3, + module: route4, name: "chatgpt_desktop_search_threads" }), "tool:grok-bot/chatgpt_desktop_send": Object.freeze({ @@ -59692,7 +59926,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": false }, - "description": "Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer \"Start new chat in \". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.", + "description": "Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -59703,15 +59937,20 @@ var __webpack_modules__ = { "type": "number" }, "project": { - "description": "Preferred project for new chats (Start new chat in ).", + "description": "With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.", "type": "string" }, "text": { "type": "string" }, "threadId": { - "description": "Sidebar thread id; omit to start a new chat.", + "description": "local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.", "type": "string" + }, + "unarchive": { + "default": false, + "description": "Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.", + "type": "boolean" } }, "required": [ @@ -59726,7 +59965,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_send", kind: "tool", - module: route4, + module: route5, name: "chatgpt_desktop_send" }), "tool:grok-bot/chatgpt_desktop_status": Object.freeze({ @@ -59734,7 +59973,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.", + "description": "Check local ChatGPT Desktop CDP before send, wait, or open. reachable:false and exitCode:1 mean CDP is down even if appServerFallback.reachable is true; list/search/read may still work through app-server. There is no remote CDP transport.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -59750,7 +59989,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_status", kind: "tool", - module: route5, + module: route6, name: "chatgpt_desktop_status" }), "tool:grok-bot/chatgpt_desktop_wait_reply": Object.freeze({ @@ -59758,7 +59997,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.", + "description": "After chatgpt_desktop_send, wait for the selected Desktop reply over CDP. Accept the returned durable local: or the temporary local:client-new-thread:* while selected; omit threadId only when staying on the same selected chat. Returns reply, durable threadId and conversationId. timeout is not proof the send failed; CDP_UNREACHABLE requires Desktop recovery. Remote ids must be handled on their hostId.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -59766,9 +60005,11 @@ var __webpack_modules__ = { "type": "number" }, "threadId": { + "description": "Durable local:, bare id, or selected local:client-new-thread:* from send.", "type": "string" }, "timeoutMs": { + "default": 120000, "type": "number" } }, @@ -59782,7 +60023,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/chatgpt_desktop_wait_reply", kind: "tool", - module: route6, + module: route7, name: "chatgpt_desktop_wait_reply" }), "tool:grok-bot/claude_send": Object.freeze({ @@ -59817,7 +60058,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/claude_send", kind: "tool", - module: route7, + module: route8, name: "claude_send" }), "tool:grok-bot/codex_send": Object.freeze({ @@ -59897,7 +60138,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_send", kind: "tool", - module: route8, + module: route9, name: "codex_send" }), "tool:grok-bot/codex_threads": Object.freeze({ @@ -59931,7 +60172,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_threads", kind: "tool", - module: route9, + module: route10, name: "codex_threads" }), "tool:grok-bot/codex_wait": Object.freeze({ @@ -59980,7 +60221,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_wait", kind: "tool", - module: route10, + module: route11, name: "codex_wait" }), "tool:grok-bot/codex_watch": Object.freeze({ @@ -60022,7 +60263,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/codex_watch", kind: "tool", - module: route11, + module: route12, name: "codex_watch" }), "tool:grok-bot/gbot_bridge_start": Object.freeze({ @@ -60063,7 +60304,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_bridge_start", kind: "tool", - module: route12, + module: route13, name: "gbot_bridge_start" }), "tool:grok-bot/gbot_bridge_status": Object.freeze({ @@ -60088,7 +60329,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_bridge_status", kind: "tool", - module: route13, + module: route14, name: "gbot_bridge_status" }), "tool:grok-bot/gbot_bridge_stop": Object.freeze({ @@ -60116,7 +60357,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_bridge_stop", kind: "tool", - module: route14, + module: route15, name: "gbot_bridge_stop" }), "tool:grok-bot/gbot_codex_respond": Object.freeze({ @@ -60174,7 +60415,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_codex_respond", kind: "tool", - module: route15, + module: route16, name: "gbot_codex_respond" }), "tool:grok-bot/gbot_grok_approvals": Object.freeze({ @@ -60204,7 +60445,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_grok_approvals", kind: "tool", - module: route16, + module: route17, name: "gbot_grok_approvals" }), "tool:grok-bot/gbot_grok_respond": Object.freeze({ @@ -60250,7 +60491,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_grok_respond", kind: "tool", - module: route17, + module: route18, name: "gbot_grok_respond" }), "tool:grok-bot/gbot_send": Object.freeze({ @@ -60310,7 +60551,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_send", kind: "tool", - module: route18, + module: route19, name: "gbot_send" }), "tool:grok-bot/gbot_thread": Object.freeze({ @@ -60355,7 +60596,7 @@ var __webpack_modules__ = { }, id: "tool:grok-bot/gbot_thread", kind: "tool", - module: route19, + module: route20, name: "gbot_thread" }) }); diff --git a/artifact/skills/chatgpt-desktop/SKILL.md b/artifact/skills/chatgpt-desktop/SKILL.md new file mode 100644 index 0000000..07a024b --- /dev/null +++ b/artifact/skills/chatgpt-desktop/SKILL.md @@ -0,0 +1,60 @@ +--- +name: chatgpt-desktop +description: Use the gbot ChatGPT Desktop MCP tools to discover hosts and threads, page/search/read conversations, and send or wait for replies on the user's Mac. Use for local Desktop CDP automation and remote-control thread routing; do not use for ordinary Grok Bot messaging. +--- +# ChatGPT Desktop through gbot + +Use the `chatgpt_desktop_*` MCP tools on the user's Mac. The CLI is a secondary +surface. CDP listens on `127.0.0.1` only; these tools do not transport CDP to +another machine. + +## Find the right conversation + +1. Call `chatgpt_desktop_status`. `reachable: false` or `exitCode: 1` means + CDP is down: open/send/wait cannot work. `appServerFallback.reachable` is a + separate list/search/read probe. Do not retry a send because CDP disappeared. +2. Call `chatgpt_desktop_list_hosts` for dynamic host IDs, labels, and + `modelProvider` values. `local` is this Mac. A remote-control host ID looks + like `remote-control:env_e_...`; its `hostName` may be `null`. Do not infer a + host name from a project label. Managed SSH hosts may have no threads. +3. Use `chatgpt_desktop_list_threads` with `host`, `modelProvider`, or `project` + as needed. Pass `nextCursor` back as `cursor` with the same filters until it + is `null`. `chatgpt_desktop_search_threads` scans metadata for a substring; + inspect `warnings` if a source failed or the scan was capped. +4. Read with `chatgpt_desktop_read_thread`. `full: false` gets the recent tail; + `full: true` pages from the start (up to 2,000 turns unless `limit` is set). + Check `complete` and `warnings` before treating it as full history. A turn + may contain both `userText` and `assistantText`. + +Durable local IDs are `local:` (a bare conversation ID also +works). `local:client-new-thread:*` is temporary and works only while that +conversation remains selected. `REMOTE_THREAD_NOT_LOADED` includes the +owning `hostId`: read or send through gbot running on that host's own Desktop +or app-server. The local Mac cannot fetch that remote history through CDP. + +## Open, send, and wait + +- `chatgpt_desktop_open_thread` navigates to a durable conversation even if it + is absent from the sidebar. An archived route returns `archived: true`; the + thread remains readable through `chatgpt_desktop_read_thread`. +- `chatgpt_desktop_send` with `threadId` sends to that conversation. Omit + `threadId` and `project` to start outside a project. Omit `threadId` and set + `project` to start inside that project. Send once. A new-thread receipt may + include `temporaryThreadId` and resolves `threadId` to the durable + `local:` before returning. Keep both until the durable ID is + confirmed; use the durable ID for later work. +- Then call `chatgpt_desktop_wait_reply` with the returned `threadId` (or the + selected temporary ID). It returns the reply and durable `conversationId`. + A timeout is an observation, not permission to resend. + +`ARCHIVED_THREAD` means send was rejected before submission. Read remains +available. Pass `unarchive: true` with an existing `threadId` on send only if +the user wants the archive state changed; this explicitly calls app-server +`thread/unarchive` and retries once. Never unarchive merely to read or open. + +`COMPOSER_HAS_DRAFT` means the user's draft would be disturbed; leave it for +the operator. `CDP_UNREACHABLE` requires restoring the local Desktop CDP +endpoint. App-server failures, including oversized frames, appear as errors or +read `warnings` with `complete: false`; inspect the partial result and source +status before continuing. A send with unknown delivery must not be repeated +without checking the selected thread and reply state. diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index c60235d..2e508b3 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -36,9 +36,12 @@ gbot chatgpt-desktop threads --limit 20 gbot chatgpt-desktop threads --limit 20 --cursor gbot chatgpt-desktop threads --host local gbot chatgpt-desktop threads --host --model-provider +gbot chatgpt-desktop threads --project gbot chatgpt-desktop search "launch" --host all gbot chatgpt-desktop read gbot chatgpt-desktop send --thread-id "hello" +gbot chatgpt-desktop send --thread-id --unarchive "hello" +gbot chatgpt-desktop send --project "new chat in project" gbot chatgpt-desktop send "start a new chat with this text" ``` @@ -52,12 +55,14 @@ allowed values with `gbot chatgpt-desktop hosts` / `chatgpt_desktop_list_hosts`. | `chatgpt_desktop_status` | CDP `/json/version` (+ optional attach) and app-server probe | | `chatgpt_desktop_list_hosts` | Discover hosts + modelProviders (no hardcoding) | | `chatgpt_desktop_list_threads` | App-server `thread/list`; merge CDP UI + remotes | +| `chatgpt_desktop_open_thread` | Navigate an existing local thread by conversation id; report archived routes | | `chatgpt_desktop_search_threads` | App-server list + metadata filter | | `chatgpt_desktop_read_thread` | App-server `thread/read` + `thread/turns/list` (`itemsView: "full"`) | -| `chatgpt_desktop_send` | Composer submit over CDP (new-thread-in-project included) | +| `chatgpt_desktop_send` | Composer submit over CDP; omit `threadId` for a new chat inside or outside a project | | `chatgpt_desktop_wait_reply` | Poll for a new assistant turn over CDP | -Every list/read/send/wait/open result includes `backend: "cdp" | "app-server"`. +Results identify the contributing backends, including `app-server+cdp` and +`remote-state` when applicable. ## Thread id mapping @@ -100,12 +105,13 @@ list filter, not a field. ### Host and modelProvider filters (separate) -`chatgpt_desktop_list_threads` / search take two independent filters: +`chatgpt_desktop_list_threads` / search accept these independent filters: | Filter | Values (any string — not an enum) | Default | Effect | | --- | --- | --- | --- | | `host` | `all` \| `local` \| any hostId / friendly name from `list_hosts` | `all` | Machine/location from remote summaries + local | | `modelProvider` | any provider id from `list_hosts` | omit / `[]` = all | Passed through to app-server `modelProviders` | +| `project` | Desktop project label or app-server projectId | omit = all | Match rows with that project | New machines or connections appear in `list_hosts` with **no code change**. @@ -163,6 +169,13 @@ cannot be mistaken for a complete app-server read. A turn may contain both `userText` and `assistantText`; `endedAt` uses the app-server `completedAt`. Full reads page from the oldest turn until completion, with a default cap of 2000 turns; an explicit `limit` can lower that cap. +Archived local threads remain readable through app-server. The open tool +navigates to their route and returns `archived: true`. Send returns +`ARCHIVED_THREAD` before submitting. Only `unarchive: true` with an existing +thread ID explicitly calls app-server `thread/unarchive`, then retries the +send once; neither open nor read changes archive state. New-thread sends return +a durable `local:` once resolved and include the temporary +`local:client-new-thread:*` ID when the sidebar exposes one. Archived conversations can be read through app-server, but Desktop requires an explicit unarchive before opening them for interaction. diff --git a/src/cli/chatgpt-desktop/search.tsx b/src/cli/chatgpt-desktop/search.tsx index da6bded..53b17d2 100644 --- a/src/cli/chatgpt-desktop/search.tsx +++ b/src/cli/chatgpt-desktop/search.tsx @@ -32,6 +32,7 @@ export const config = { 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string', }, + project: { description: 'Project label or projectId filter.', type: 'string' }, port: { description: 'Local CDP port', type: 'number' }, query: { type: 'string' }, }, @@ -46,6 +47,7 @@ export const inputSchema = z host: z.string().min(1).max(256).optional(), limit: z.number().int().min(1).max(200).default(50), modelProvider: z.string().min(1).max(256).optional(), + project: z.string().min(1).max(256).optional(), port: z.number().int().min(1).max(65535).optional(), query: z.string().min(1).max(512), }) diff --git a/src/cli/chatgpt-desktop/send.tsx b/src/cli/chatgpt-desktop/send.tsx index 670f962..2be5741 100644 --- a/src/cli/chatgpt-desktop/send.tsx +++ b/src/cli/chatgpt-desktop/send.tsx @@ -21,6 +21,7 @@ export const config = { project: { type: 'string' }, text: { type: 'array', items: { type: 'string' } }, threadId: { type: 'string' }, + unarchive: { type: 'boolean', description: 'Explicitly unarchive an existing archived thread before sending.' }, }, required: ['text'], type: 'object', @@ -35,6 +36,7 @@ export const inputSchema = z project: z.string().min(1).max(256).optional(), text: z.array(z.string()).min(1), threadId: z.string().min(1).max(256).optional(), + unarchive: z.boolean().default(false), }) .strict(); export { resultSchema }; @@ -47,6 +49,7 @@ export default async function chatgptDesktopSend({ threadId: input.threadId, text: input.text.join(' ').trim(), project: input.project, + unarchive: input.unarchive, openTimeoutMs: input.openTimeoutMs, }); return ( diff --git a/src/cli/chatgpt-desktop/threads.tsx b/src/cli/chatgpt-desktop/threads.tsx index 8c4170c..0a9201a 100644 --- a/src/cli/chatgpt-desktop/threads.tsx +++ b/src/cli/chatgpt-desktop/threads.tsx @@ -32,6 +32,7 @@ export const config = { 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string', }, + project: { description: 'Project label or projectId filter.', type: 'string' }, port: { description: 'Local CDP port', type: 'number' }, }, type: 'object', @@ -45,6 +46,7 @@ export const inputSchema = z limit: z.number().int().min(1).max(200).default(50), cursor: z.string().min(1).max(4096).optional(), modelProvider: z.string().min(1).max(256).optional(), + project: z.string().min(1).max(256).optional(), port: z.number().int().min(1).max(65535).optional(), }) .strict(); diff --git a/src/core/chatgpt-desktop/adapter.ts b/src/core/chatgpt-desktop/adapter.ts index c1d5453..919bdab 100644 --- a/src/core/chatgpt-desktop/adapter.ts +++ b/src/core/chatgpt-desktop/adapter.ts @@ -23,6 +23,7 @@ export interface ChatGptDesktopAdapter { host?: string; /** Any modelProvider id (app-server modelProviders). Omit = all. See list_hosts. Not an enum. */ modelProvider?: string; + project?: string; groupBy?: 'host'; }): Promise; /** Optional; facades that support app-server search implement this. */ @@ -33,6 +34,7 @@ export interface ChatGptDesktopAdapter { host?: string; /** Any modelProvider id; see list_hosts. Not an enum. */ modelProvider?: string; + project?: string; groupBy?: 'host'; }): Promise; /** @@ -56,6 +58,7 @@ export interface ChatGptDesktopAdapter { threadId?: string; text: string; project?: string; + unarchive?: boolean; openTimeoutMs?: number; }): Promise; waitForReply(options: { diff --git a/src/core/chatgpt-desktop/app-server-fallback.ts b/src/core/chatgpt-desktop/app-server-fallback.ts index f050ac0..0447b70 100644 --- a/src/core/chatgpt-desktop/app-server-fallback.ts +++ b/src/core/chatgpt-desktop/app-server-fallback.ts @@ -53,10 +53,12 @@ export async function appServerSearchThreads({ query, limit = 50, modelProviders = [], + project, }: { query: string; limit?: number; modelProviders?: string[]; + project?: string; }): Promise { const needle = query.trim().toLowerCase(); if (!needle) { @@ -69,7 +71,9 @@ export async function appServerSearchThreads({ const out = await listCodexThreads({ limit: 25, cursor, modelProviders }); for (const thread of out.threads) { const mapped = mapListedThread(thread); - if (threadMatchesQuery(mapped, needle)) matched.push(mapped); + if (threadMatchesQuery(mapped, needle) + && (!project || [mapped.project, mapped.projectId].some((value) => + typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase())))) matched.push(mapped); if (matched.length >= limit) break; } if (out.nextCursor == null || typeof out.nextCursor !== 'string') { exhausted = true; break; } @@ -152,6 +156,22 @@ export async function appServerReadThread({ } } +/** Explicit opt-in only. The local app-server owns the archive mutation. */ +export async function appServerUnarchiveThread(threadId: string): Promise { + const bare = requireAppServerThreadId(threadId); + const { client } = await openCodexSession(); + try { + const result = await client.request('thread/unarchive', { threadId: bare }); + if (!result || typeof result !== 'object' || !('thread' in result) + || !result.thread || typeof result.thread !== 'object' + || !('id' in result.thread) || result.thread.id !== bare) { + throw new Error(`thread/unarchive returned no thread for ${bare}`); + } + } finally { + client.close(); + } +} + async function readLocalThread( bare: string, { limit, full }: { limit: number; full: boolean }, diff --git a/src/core/chatgpt-desktop/cdp-adapter.ts b/src/core/chatgpt-desktop/cdp-adapter.ts index ad26672..0487d8b 100644 --- a/src/core/chatgpt-desktop/cdp-adapter.ts +++ b/src/core/chatgpt-desktop/cdp-adapter.ts @@ -1,5 +1,5 @@ import type { ChatGptDesktopAdapter } from './adapter.js'; -import { CdpUnreachableError } from './errors.js'; +import { ArchivedThreadError, CdpUnreachableError } from './errors.js'; import { CdpSession } from './cdp-session.js'; import { DEFAULT_CONVERSATION_RESOLVE_MS, @@ -224,7 +224,12 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { { openTimeoutMs = DEFAULT_OPEN_TIMEOUT_MS }: { openTimeoutMs?: number } = {}, ): Promise { const sessionId = await this.#ensurePageSession(); - await this.#openAndWait(sessionId, threadId, openTimeoutMs); + try { + await this.#openAndWait(sessionId, threadId, openTimeoutMs); + } catch (error) { + if (error instanceof ArchivedThreadError) return { threadId, backend: 'cdp', archived: true }; + throw error; + } return { threadId, backend: 'cdp' }; } diff --git a/src/core/chatgpt-desktop/cdp-dom.ts b/src/core/chatgpt-desktop/cdp-dom.ts index 2894c0a..0e87f9c 100644 --- a/src/core/chatgpt-desktop/cdp-dom.ts +++ b/src/core/chatgpt-desktop/cdp-dom.ts @@ -7,6 +7,7 @@ import type { ChatGptDesktopTarget, ChatGptDesktopThread, ChatGptDesktopTurn } from './types.js'; import type { CdpSession } from './cdp-session.js'; +import { ArchivedThreadError, ComposerDraftError } from './errors.js'; import { LOCAL_THREAD_ID_PREFIX, isTemporaryDesktopThreadId, @@ -461,7 +462,7 @@ export async function waitForLoadingTaskGone( if (threadId && threadId !== 'new' && await session.evaluate(ARCHIVED_THREAD_EXPRESSION, { sessionId }) === true) { archivedSince ??= Date.now(); if (Date.now() - archivedSince >= 500) { - throw new Error(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived; unarchive it in Desktop before opening`); + throw new ArchivedThreadError(threadId); } } else { archivedSince = null; @@ -529,6 +530,7 @@ export async function focusComposer( { sessionId }, ); if (!focused?.ok) { + if (focused?.error === 'composer-has-draft') throw new ComposerDraftError(); throw new Error(`ChatGPT Desktop composer unavailable: ${focused?.error || 'not found'}`); } } diff --git a/src/core/chatgpt-desktop/errors.ts b/src/core/chatgpt-desktop/errors.ts index b14a9f6..47f2e5a 100644 --- a/src/core/chatgpt-desktop/errors.ts +++ b/src/core/chatgpt-desktop/errors.ts @@ -1,5 +1,31 @@ export { RemoteThreadNotLoadedError } from '../codex/remote-control.js'; +/** Desktop opened the route but requires explicit unarchive before interaction. */ +export class ArchivedThreadError extends Error { + readonly code = 'ARCHIVED_THREAD' as const; + readonly reason = 'archived-thread' as const; + readonly delivery = 'rejected' as const; + readonly threadId: string; + + constructor(threadId: string) { + super(`ChatGPT Desktop thread ${JSON.stringify(threadId)} is archived. Read it through app-server, or pass unarchive: true on send to unarchive before sending.`); + this.name = 'ArchivedThreadError'; + this.threadId = threadId; + } +} + +/** Sending would replace an operator's unsent composer draft. */ +export class ComposerDraftError extends Error { + readonly code = 'COMPOSER_HAS_DRAFT' as const; + readonly reason = 'composer-has-draft' as const; + readonly delivery = 'rejected' as const; + + constructor() { + super('ChatGPT Desktop composer contains an unsent draft; inspect it in Desktop before sending.'); + this.name = 'ComposerDraftError'; + } +} + /** Typed failure when a ChatGPT Desktop CDP/DOM operation is not yet implemented. */ export class NotImplementedError extends Error { readonly code = 'NOT_IMPLEMENTED' as const; diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index 5958051..4045450 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -3,13 +3,14 @@ import { CdpChatGptDesktopAdapter } from './cdp-adapter.js'; import { appServerListThreads, appServerReadThread, + appServerUnarchiveThread, appServerSearchThreads, appServerStatusProbe, discoverModelProviders, } from './app-server-fallback.js'; -import { CdpUnreachableError, NotImplementedError, RemoteThreadNotLoadedError } from './errors.js'; +import { ArchivedThreadError, CdpUnreachableError, NotImplementedError, RemoteThreadNotLoadedError } from './errors.js'; import { resolveCdpPort } from './loopback.js'; -import { listDiscoveredHosts, listRemoteThreadsFromState } from './remote-threads.js'; +import { findRemoteThread, listDiscoveredHosts, listRemoteThreadsFromState } from './remote-threads.js'; import { isTemporaryDesktopThreadId, threadIdsEquivalent, @@ -33,6 +34,7 @@ export type ChatGptDesktopFallbacks = { listThreads: typeof appServerListThreads; searchThreads: typeof appServerSearchThreads; readThread: typeof appServerReadThread; + unarchiveThread?: typeof appServerUnarchiveThread; statusProbe: typeof appServerStatusProbe; listRemoteThreads?: typeof listRemoteThreadsFromState; listHosts?: typeof listDiscoveredHosts; @@ -43,6 +45,7 @@ const defaultFallbacks: ChatGptDesktopFallbacks = { listThreads: appServerListThreads, searchThreads: appServerSearchThreads, readThread: appServerReadThread, + unarchiveThread: appServerUnarchiveThread, statusProbe: appServerStatusProbe, listRemoteThreads: listRemoteThreadsFromState, listHosts: listDiscoveredHosts, @@ -67,6 +70,8 @@ export type ListThreadsOptions = { * see `listHosts` / `chatgpt_desktop_list_hosts`. */ modelProvider?: string; + /** Match a Desktop project label or app-server projectId. */ + project?: string; /** When `"host"`, also return `groups` keyed by host (grouping mode). */ groupBy?: 'host'; }; @@ -141,7 +146,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { const remoteInventory = finalizeThreadList({ backend: cdpList?.backend ?? 'remote-state', limit: 10_000, threads: cdpList?.threads.filter((thread) => thread.location === 'remote') ?? [], - }, { limit: 10_000, host, modelProvider: options.modelProvider, remotes }); + }, { limit: 10_000, host, modelProvider: options.modelProvider, project: options.project, remotes }); const offset = remoteOffset ?? 0; if (remoteOffset !== null || remoteInventory.threads.length >= limit) { const page = remoteInventory.threads.slice(offset, offset + limit); @@ -155,9 +160,11 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { const remoteKeys = new Set(remotes.map((thread) => toAppServerThreadId(thread.threadId) ?? thread.threadId)); const reservedRemoteRows = host === 'all' && inventoryPage - ? remotes.filter((thread) => modelProviderMatches(thread, options.modelProvider)).length + ? remotes.filter((thread) => modelProviderMatches(thread, options.modelProvider) + && projectMatches(thread, options.project)).length + (cdpList?.threads.filter((thread) => thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) + && projectMatches(thread, options.project) && !remoteKeys.has(toAppServerThreadId(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); @@ -183,6 +190,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes, }); @@ -299,6 +307,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { limit?: number; host?: string; modelProvider?: string; + project?: string; groupBy?: 'host'; }): Promise { const limit = options.limit ?? 50; @@ -309,6 +318,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { query: options.query, limit, modelProviders, + project: options.project, }); const cdpList = await this.#tryCdpList({ limit }); const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; @@ -316,6 +326,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { limit: 10_000, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, remotes: this.#listRemotes(), }); const needle = options.query.trim().toLowerCase(); @@ -328,6 +339,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes: [], }); @@ -346,6 +358,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { limit, host, modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, groupBy: options.groupBy, remotes: remotes.filter((thread) => threadMatchesQuery(thread, needle)), }); @@ -386,10 +399,21 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { threadId?: string; text: string; project?: string; + unarchive?: boolean; openTimeoutMs?: number; }): Promise { + if (options.threadId) { + const remote = findRemoteThread(options.threadId); + if (remote) throw new RemoteThreadNotLoadedError(options.threadId, remote.hostId, remote.hostName); + } await this.#ensureCdp(); - return this.#cdp.sendMessage(options); + try { + return await this.#cdp.sendMessage(options); + } catch (error) { + if (!(error instanceof ArchivedThreadError) || !options.unarchive || !options.threadId) throw error; + await (this.#fallbacks.unarchiveThread ?? appServerUnarchiveThread)(options.threadId); + return this.#cdp.sendMessage({ ...options, unarchive: false }); + } } async waitForReply(options: { @@ -404,6 +428,8 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { threadId: string, options?: { openTimeoutMs?: number }, ): Promise { + const remote = findRemoteThread(threadId); + if (remote) throw new RemoteThreadNotLoadedError(threadId, remote.hostId, remote.hostName); await this.#ensureCdp(); return this.#cdp.openThread(threadId, options); } @@ -529,12 +555,14 @@ export function finalizeThreadList( limit, host = 'all', modelProvider, + project, groupBy, remotes, }: { limit: number; host?: string; modelProvider?: string; + project?: string; groupBy?: 'host'; remotes: readonly ChatGptDesktopThread[]; }, @@ -575,6 +603,7 @@ export function finalizeThreadList( const filtered = merged.filter((thread) => { if (!hostMatches(thread, host)) return false; if (!modelProviderMatches(thread, modelProvider)) return false; + if (!projectMatches(thread, project)) return false; return true; }); const limited = filtered.slice(0, limit); @@ -590,6 +619,7 @@ export function finalizeThreadList( ...(base.query !== undefined ? { query: base.query } : {}), host, ...(modelProvider ? { modelProvider } : {}), + ...(project ? { project } : {}), }; if (groupBy === 'host') { return { ...result, groupBy: 'host', groups: groupThreadsByHost(limited) }; @@ -643,6 +673,13 @@ function modelProviderMatches(thread: ChatGptDesktopThread, modelProvider?: stri return thread.modelProvider === modelProvider; } +function projectMatches(thread: ChatGptDesktopThread, project?: string): boolean { + if (!project) return true; + const needle = project.trim().toLowerCase(); + return [thread.project, thread.projectId].some((value) => + typeof value === 'string' && value.toLowerCase().includes(needle)); +} + function threadMatchesQuery(thread: ChatGptDesktopThread, needle: string): boolean { if (!needle) return true; return [thread.title, thread.threadId, thread.project, thread.preview, thread.hostName, thread.hostId] diff --git a/src/core/chatgpt-desktop/index.ts b/src/core/chatgpt-desktop/index.ts index 716a695..fd787b1 100644 --- a/src/core/chatgpt-desktop/index.ts +++ b/src/core/chatgpt-desktop/index.ts @@ -28,6 +28,8 @@ export { } from './cdp-dom.js'; export { CdpSession } from './cdp-session.js'; export { + ArchivedThreadError, + ComposerDraftError, CdpHostRejectedError, CdpUnreachableError, NotImplementedError, diff --git a/src/core/chatgpt-desktop/routes.ts b/src/core/chatgpt-desktop/routes.ts index 5be1fdf..de21167 100644 --- a/src/core/chatgpt-desktop/routes.ts +++ b/src/core/chatgpt-desktop/routes.ts @@ -30,6 +30,7 @@ export const listThreadsSchema = z * `chatgpt_desktop_list_hosts`. Not an enum. */ modelProvider: z.string().min(1).max(256).optional(), + project: z.string().min(1).max(256).optional(), groupBy: z.literal('host').optional(), }) .strict(); @@ -43,6 +44,7 @@ export const searchThreadsSchema = z host: z.string().min(1).max(256).optional(), /** Any modelProvider id; see `chatgpt_desktop_list_hosts`. Not an enum. */ modelProvider: z.string().min(1).max(256).optional(), + project: z.string().min(1).max(256).optional(), groupBy: z.literal('host').optional(), }) .strict(); @@ -63,15 +65,28 @@ export const readThreadSchema = z }) .strict(); +export const openThreadSchema = z.object({ + port: z.number().int().min(1).max(65535).optional(), + threadId, + openTimeoutMs: z.number().int().min(1).max(600_000).default(90_000), +}).strict(); + export const sendSchema = z .object({ port: z.number().int().min(1).max(65535).optional(), threadId: threadId.optional(), text: z.string().trim().min(1).max(100_000), project: z.string().min(1).max(256).optional(), + unarchive: z.boolean().default(false), openTimeoutMs: z.number().int().min(1).max(600_000).default(90_000), }) - .strict(); + .strict() + .refine((value) => !value.unarchive || Boolean(value.threadId), { + message: 'unarchive requires an existing threadId', path: ['unarchive'], + }) + .refine((value) => !value.threadId || !value.project, { + message: 'project is only for a new thread; omit threadId', path: ['project'], + }); export const waitReplySchema = z .object({ @@ -169,6 +184,7 @@ export async function listThreadsOperation( cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, + project: input.project, groupBy: input.groupBy, }), ); @@ -191,6 +207,7 @@ export async function searchThreadsOperation( limit: input.limit, host: input.host, modelProvider: input.modelProvider, + project: input.project, groupBy: input.groupBy, }); }); @@ -234,6 +251,15 @@ export async function readThreadOperation( } } +export async function openThreadOperation(input: z.infer): Promise { + try { + const out = await withAdapter(input.port, (adapter) => adapter.openThread(input.threadId, { openTimeoutMs: input.openTimeoutMs })); + return asResult({ ...out, exitCode: 0 as const }); + } catch (error) { + return mapError(error); + } +} + export async function sendOperation(input: z.infer): Promise { try { input = sendSchema.parse(input); @@ -242,6 +268,7 @@ export async function sendOperation(input: z.infer): Promise< threadId: input.threadId, text: input.text, project: input.project, + unarchive: input.unarchive, openTimeoutMs: input.openTimeoutMs, }), ); diff --git a/src/core/chatgpt-desktop/types.ts b/src/core/chatgpt-desktop/types.ts index 383e171..39921e6 100644 --- a/src/core/chatgpt-desktop/types.ts +++ b/src/core/chatgpt-desktop/types.ts @@ -91,6 +91,7 @@ export type ListThreadsResult = { readonly host?: string; /** Model-provider filter (any string; see list_hosts). Passed through to app-server `modelProviders`. */ readonly modelProvider?: string; + readonly project?: string; readonly groupBy?: 'host'; /** Present when `groupBy: "host"`. */ readonly groups?: readonly ChatGptDesktopHostGroup[]; @@ -158,4 +159,5 @@ export type WaitForReplyResult = { export type OpenThreadResult = { readonly threadId: string; readonly backend: ChatGptDesktopBackend; + readonly archived?: boolean; }; diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx index 5ce90cc..ff0869f 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list hosts', description: - 'Discover local, remote-control, and managed SSH hosts from Desktop state, including nested remote-thread summaries. Host names are null when Desktop has no display name. Providers come from paged app-server inventory and remote summaries. Result includes sources and discovery warnings.', + 'Discover local, remote-control environment ids, managed SSH hosts, and modelProvider ids. hostName is null when Desktop has no real display name. Use hostId or label in list/search filters; remote thread ids must be read on the owning host. warnings report provider discovery failures.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx index 4f3e571..7a5e03a 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list threads', description: - 'Page ChatGPT Desktop / Codex threads with cursor and nextCursor. Merges local app-server rows, CDP sidebar rows, and nested remote-control summaries. Discover dynamic host and modelProvider filters via chatgpt_desktop_list_hosts. Optional groupBy=host. Result reports the contributing backends and warnings.', + 'List Desktop threads, then pass nextCursor as cursor until null. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -22,8 +22,8 @@ export default defineTool( additionalProperties: false, properties: { port: { type: 'number' }, - limit: { type: 'number', description: 'Maximum threads (1-200).' }, - cursor: { type: 'string', description: 'Opaque nextCursor from a previous page.' }, + limit: { type: 'number', default: 50, description: 'Maximum threads per page.' }, + cursor: { type: 'string', description: 'Opaque nextCursor from the prior page; keep filters unchanged.' }, host: { type: 'string', description: @@ -34,6 +34,7 @@ export default defineTool( description: 'Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.', }, + project: { type: 'string', description: 'Match a Desktop project label or app-server projectId. Dynamic string, not an enum.' }, groupBy: { type: 'string', enum: ['host'], diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx new file mode 100644 index 0000000..8cfb196 --- /dev/null +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx @@ -0,0 +1,39 @@ +import { Agent } from '@agent-bundle/runtime'; +import { defineTool } from 'agent-bundle/routes'; +import { + openThreadOperation, + openThreadSchema as inputSchema, + resultSchema, + resultText, +} from '../../../core/chatgpt-desktop/routes.js'; + +export { inputSchema }; + +export default defineTool( + { + title: 'ChatGPT Desktop open thread', + description: + 'Navigate Desktop to an existing local: or bare conversation id, even when the row is absent from the sidebar. Archived routes return archived:true without unarchiving; read them with chatgpt_desktop_read_thread. A remote-control id is owned by its hostId and cannot be opened on this Mac. CDP_UNREACHABLE means Desktop must be reachable locally.', + annotations: { readOnlyHint: true }, + inputSchema, + resultSchema, + inputJsonSchema: { + type: 'object', + additionalProperties: false, + properties: { + port: { type: 'number', description: 'Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).' }, + threadId: { type: 'string', description: 'local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.' }, + openTimeoutMs: { type: 'number', description: 'Maximum time to wait for the requested conversation (1-600000 ms).' }, + }, + required: ['threadId'], + }, + }, + async (input) => { + const out = await openThreadOperation(input); + return ( + + {resultText(out)} + + ); + }, +); diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx index 3636958..a8c356c 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop read thread', description: - 'Read paged ChatGPT Desktop turns through app-server, including userText, assistantText, and completedAt as endedAt. Remote-only threads return REMOTE_THREAD_NOT_LOADED with hostId. CDP fallback reports complete:false and a warning when app-server fails. Result includes backend.', + 'Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Recent defaults to 100 turns; full pages up to 2000 from the start. Archived threads remain readable. complete:false means partial history; warnings preserve app-server/frame errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -26,7 +26,7 @@ export default defineTool( threadId: { type: 'string', description: - 'Desktop sidebar id (local:) or bare app-server thread id.', + 'local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.', }, limit: { type: 'number' }, full: { diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx index 9f8bfe7..c816c5e 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop search threads', description: - 'Search ChatGPT Desktop / Codex threads through the local app-server and remote-control summaries. Separate filters host and modelProvider accept any string (not enums) — discover allowed values via chatgpt_desktop_list_hosts. Optional groupBy=host. Result includes backend.', + 'Search Desktop thread metadata by case-insensitive substring. Dynamic hostId/hostName, modelProvider, and project filters apply. Search scans bounded app-server pages and reports warnings if incomplete; use list_threads cursor for exhaustive paging. Remote results identify hostId and cannot be read on this Mac.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -23,7 +23,7 @@ export default defineTool( properties: { port: { type: 'number' }, query: { type: 'string', description: 'Case-insensitive substring over thread metadata.' }, - limit: { type: 'number', description: 'Maximum matches (1-200).' }, + limit: { type: 'number', default: 50, description: 'Maximum matches.' }, host: { type: 'string', description: @@ -34,6 +34,7 @@ export default defineTool( description: 'Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.', }, + project: { type: 'string', description: 'Match a Desktop project label or app-server projectId.' }, groupBy: { type: 'string', enum: ['host'], diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx index d854187..4cc5b05 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop send', description: - 'Send a message in ChatGPT Desktop via local CDP only: focus [data-codex-composer], Input.insertText, Enter (Send button fallback). Omit threadId to start a new chat; pass project to prefer "Start new chat in ". After a new-thread send, waits for data-response-annotation-conversation and returns that durable id as threadId (never local:client-new-thread:*). temporaryThreadId may still name the brief sidebar row. Does not use app-server.', + 'Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.', annotations: { readOnlyHint: false }, inputSchema, resultSchema, @@ -23,12 +23,13 @@ export default defineTool( additionalProperties: false, properties: { port: { type: 'number' }, - threadId: { type: 'string', description: 'Sidebar thread id; omit to start a new chat.' }, + threadId: { type: 'string', description: 'local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.' }, text: { type: 'string' }, project: { type: 'string', - description: 'Preferred project for new chats (Start new chat in ).', + description: 'With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.', }, + unarchive: { type: 'boolean', default: false, description: 'Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.' }, openTimeoutMs: { type: 'number' }, }, required: ['text'], diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx index 618b749..427b9c8 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop status', description: - 'Probe the local ChatGPT Desktop Chrome DevTools endpoint on 127.0.0.1 (no remote transport). Reports CDP reachability and whether the Codex app-server is available for list/deep-read. From the Grok Bot box, run gbot on the user machine via Grok Bot Shell with a machineId.', + 'Check local ChatGPT Desktop CDP before send, wait, or open. reachable:false and exitCode:1 mean CDP is down even if appServerFallback.reachable is true; list/search/read may still work through app-server. There is no remote CDP transport.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx index 79f88f2..0026005 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop wait for reply', description: - 'Wait until main Stop is gone and a new [data-local-conversation-final-assistant=true] exists, then return assistant markdown text. Also returns conversationId from data-response-annotation-conversation (resolves temporary local:client-new-thread ids). CDP only — does not use app-server.', + 'After chatgpt_desktop_send, wait for the selected Desktop reply over CDP. Accept the returned durable local: or the temporary local:client-new-thread:* while selected; omit threadId only when staying on the same selected chat. Returns reply, durable threadId and conversationId. timeout is not proof the send failed; CDP_UNREACHABLE requires Desktop recovery. Remote ids must be handled on their hostId.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -23,8 +23,8 @@ export default defineTool( additionalProperties: false, properties: { port: { type: 'number' }, - threadId: { type: 'string' }, - timeoutMs: { type: 'number' }, + threadId: { type: 'string', description: 'Durable local:, bare id, or selected local:client-new-thread:* from send.' }, + timeoutMs: { type: 'number', default: 120000 }, }, required: [], }, diff --git a/src/skills/chatgpt-desktop/SKILL.md b/src/skills/chatgpt-desktop/SKILL.md new file mode 100644 index 0000000..07a024b --- /dev/null +++ b/src/skills/chatgpt-desktop/SKILL.md @@ -0,0 +1,60 @@ +--- +name: chatgpt-desktop +description: Use the gbot ChatGPT Desktop MCP tools to discover hosts and threads, page/search/read conversations, and send or wait for replies on the user's Mac. Use for local Desktop CDP automation and remote-control thread routing; do not use for ordinary Grok Bot messaging. +--- +# ChatGPT Desktop through gbot + +Use the `chatgpt_desktop_*` MCP tools on the user's Mac. The CLI is a secondary +surface. CDP listens on `127.0.0.1` only; these tools do not transport CDP to +another machine. + +## Find the right conversation + +1. Call `chatgpt_desktop_status`. `reachable: false` or `exitCode: 1` means + CDP is down: open/send/wait cannot work. `appServerFallback.reachable` is a + separate list/search/read probe. Do not retry a send because CDP disappeared. +2. Call `chatgpt_desktop_list_hosts` for dynamic host IDs, labels, and + `modelProvider` values. `local` is this Mac. A remote-control host ID looks + like `remote-control:env_e_...`; its `hostName` may be `null`. Do not infer a + host name from a project label. Managed SSH hosts may have no threads. +3. Use `chatgpt_desktop_list_threads` with `host`, `modelProvider`, or `project` + as needed. Pass `nextCursor` back as `cursor` with the same filters until it + is `null`. `chatgpt_desktop_search_threads` scans metadata for a substring; + inspect `warnings` if a source failed or the scan was capped. +4. Read with `chatgpt_desktop_read_thread`. `full: false` gets the recent tail; + `full: true` pages from the start (up to 2,000 turns unless `limit` is set). + Check `complete` and `warnings` before treating it as full history. A turn + may contain both `userText` and `assistantText`. + +Durable local IDs are `local:` (a bare conversation ID also +works). `local:client-new-thread:*` is temporary and works only while that +conversation remains selected. `REMOTE_THREAD_NOT_LOADED` includes the +owning `hostId`: read or send through gbot running on that host's own Desktop +or app-server. The local Mac cannot fetch that remote history through CDP. + +## Open, send, and wait + +- `chatgpt_desktop_open_thread` navigates to a durable conversation even if it + is absent from the sidebar. An archived route returns `archived: true`; the + thread remains readable through `chatgpt_desktop_read_thread`. +- `chatgpt_desktop_send` with `threadId` sends to that conversation. Omit + `threadId` and `project` to start outside a project. Omit `threadId` and set + `project` to start inside that project. Send once. A new-thread receipt may + include `temporaryThreadId` and resolves `threadId` to the durable + `local:` before returning. Keep both until the durable ID is + confirmed; use the durable ID for later work. +- Then call `chatgpt_desktop_wait_reply` with the returned `threadId` (or the + selected temporary ID). It returns the reply and durable `conversationId`. + A timeout is an observation, not permission to resend. + +`ARCHIVED_THREAD` means send was rejected before submission. Read remains +available. Pass `unarchive: true` with an existing `threadId` on send only if +the user wants the archive state changed; this explicitly calls app-server +`thread/unarchive` and retries once. Never unarchive merely to read or open. + +`COMPOSER_HAS_DRAFT` means the user's draft would be disturbed; leave it for +the operator. `CDP_UNREACHABLE` requires restoring the local Desktop CDP +endpoint. App-server failures, including oversized frames, appear as errors or +read `warnings` with `complete: false`; inspect the partial result and source +status before continuing. A send with unknown delivery must not be repeated +without checking the selected thread and reply state. diff --git a/test/host-tool-inventory.test.js b/test/host-tool-inventory.test.js index 74c6033..da7b71c 100644 --- a/test/host-tool-inventory.test.js +++ b/test/host-tool-inventory.test.js @@ -14,6 +14,7 @@ const grok = ['gbot_send', 'gbot_thread', 'gbot_grok_approvals', 'gbot_grok_resp const shared = [ 'chatgpt_desktop_list_hosts', 'chatgpt_desktop_list_threads', + 'chatgpt_desktop_open_thread', 'chatgpt_desktop_read_thread', 'chatgpt_desktop_search_threads', 'chatgpt_desktop_send', @@ -40,3 +41,34 @@ test('built MCP artifact exposes the other host tools and shared bridge controls } } }); + +test('every host projection contains the Desktop skill and every Desktop MCP tool', async () => { + const root = resolve('artifact'); + const manifest = JSON.parse(await readFile(resolve(root, 'agent-bundle.manifest.json'), 'utf8')); + const skillPath = 'skills/chatgpt-desktop/SKILL.md'; + assert.ok(manifest.files.some((file) => file.path === skillPath)); + const skill = await readFile(resolve(root, skillPath), 'utf8'); + assert.match(skill, /^---\nname: chatgpt-desktop\n/); + const desktopTools = shared.filter((name) => name.startsWith('chatgpt_desktop_')); + const manifestTools = manifest.routes.servers.flatMap((server) => server.routes) + .map((route) => route.id?.split('/').at(-1)) + .filter((name) => name?.startsWith('chatgpt_desktop_')); + assert.deepEqual(manifestTools.sort(), [...desktopTools].sort()); + for (const projection of manifest.projections.filter((item) => ['claude', 'codex', 'cursor'].includes(item.host))) { + const plugin = JSON.parse(await readFile(resolve(root, projection.documents.plugin), 'utf8')); + if (projection.host !== 'claude') assert.equal(plugin.skills, './skills/'); + const mcp = JSON.parse(await readFile(resolve(root, projection.documents.mcp), 'utf8')); + const arg = mcp.mcpServers['grok-bot'].args[0]; + const hostEntry = arg.startsWith('./') + ? resolve(root, arg) + : arg.replace(/^\$\{(?:CLAUDE|CURSOR)_PLUGIN_ROOT\}/, root); + const client = new Client({ name: projection.host, version: '1.0.0' }); + try { + await client.connect(new StdioClientTransport({ command: process.execPath, args: [hostEntry], stderr: 'pipe' })); + const listed = new Set((await client.listTools()).tools.map((tool) => tool.name)); + for (const name of desktopTools) assert.ok(listed.has(name), `${projection.host} missing ${name}`); + } finally { + await client.close(); + } + } +}); diff --git a/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts b/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts index 4cecaa8..5c771ce 100644 --- a/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts +++ b/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts @@ -42,6 +42,15 @@ it('joins a CDP row to remote ownership and reports mixed backends', () => { expect(out).toMatchObject({ backend: 'app-server+cdp+remote-state', threads: [{ location: 'remote', hostId: 'remote-control:env_dynamic', selected: true }] }); }); +it('filters thread rows by dynamic project label or projectId', () => { + const row = (id: string, project: string, projectId: string) => ({ + threadId: `local:${id}`, title: id, project, projectId, pinned: false, selected: false, kind: 'codex', + }); + const base = { backend: 'app-server' as const, limit: 10, threads: [row('one', 'core', 'project-1'), row('two', 'other', 'project-2')] }; + expect(finalizeThreadList(base, { limit: 10, project: 'core', remotes: [] }).threads.map((thread) => thread.threadId)).toEqual(['local:one']); + expect(finalizeThreadList(base, { limit: 10, project: 'project-2', remotes: [] }).threads.map((thread) => thread.threadId)).toEqual(['local:two']); +}); + it('counts CDP-only remote rows in host discovery', async () => { const row = { threadId: 'local:cdp-only', title: 'remote', pinned: false, selected: false, kind: 'remote', location: 'remote' as const, hostId: 'remote:dynamic', hostName: null }; const facade = new ChatGptDesktopFacade({ diff --git a/tests/route-unit/chatgpt-desktop-mcp-followup.test.ts b/tests/route-unit/chatgpt-desktop-mcp-followup.test.ts new file mode 100644 index 0000000..b8c34f8 --- /dev/null +++ b/tests/route-unit/chatgpt-desktop-mcp-followup.test.ts @@ -0,0 +1,162 @@ +import { afterEach, expect, it, rstest } from '@rstest/core'; +import { invokeMcpTool, listMcpSurface } from 'agent-bundle/test'; +import { CdpSession } from '../../src/core/chatgpt-desktop/cdp-session.js'; +import { CdpChatGptDesktopAdapter } from '../../src/core/chatgpt-desktop/cdp-adapter.js'; +import { ARCHIVED_THREAD_EXPRESSION, CONVERSATION_ID_EXPRESSION, FOCUS_COMPOSER_EXPRESSION, LIST_THREADS_EXPRESSION, LOADING_TASK_GONE_EXPRESSION, REPLY_STATE_EXPRESSION, focusComposer, startNewChatExpression } from '../../src/core/chatgpt-desktop/cdp-dom.js'; +import { ArchivedThreadError, ComposerDraftError } from '../../src/core/chatgpt-desktop/errors.js'; +import { ChatGptDesktopFacade, setChatGptDesktopAdapterForTests } from '../../src/core/chatgpt-desktop/facade.js'; +import { appServerUnarchiveThread } from '../../src/core/chatgpt-desktop/app-server-fallback.js'; +import { listThreadsOperation, listThreadsSchema, openThreadOperation, openThreadSchema, sendOperation, sendSchema } from '../../src/core/chatgpt-desktop/routes.js'; +import type { ChatGptDesktopAdapter } from '../../src/core/chatgpt-desktop/adapter.js'; + +afterEach(() => { rstest.restoreAllMocks(); setChatGptDesktopAdapterForTests(null); }); + +function mockCdp(evaluate: (expression: string) => unknown, onSend?: (method: string, params?: Record) => void) { + rstest.spyOn(CdpSession.prototype, 'connect').mockResolvedValue({}); + rstest.spyOn(CdpSession.prototype, 'closed', 'get').mockReturnValue(false); + rstest.spyOn(CdpSession.prototype, 'send').mockImplementation(async (method, params) => { + onSend?.(method, params); + return (method === 'Target.getTargets' + ? { targetInfos: [{ targetId: 'main', type: 'page', url: 'app://-/index.html' }] } + : { sessionId: 'page' }) as never; + }); + rstest.spyOn(CdpSession.prototype, 'evaluate').mockImplementation(async (expression) => evaluate(expression) as never); +} + +it('returns archived:true after navigating an archived thread route without unarchiving', async () => { + let navigated = false; + mockCdp((expression) => { + if (expression === CONVERSATION_ID_EXPRESSION) return ''; + if (expression.includes('router.navigate')) { navigated = true; return { ok: true }; } + if (expression.includes('rows.find((el)')) return { ok: false, error: 'thread-not-found' }; + if (expression === ARCHIVED_THREAD_EXPRESSION) return true; + if (expression === LOADING_TASK_GONE_EXPRESSION) return true; + return null; + }); + const adapter = new CdpChatGptDesktopAdapter(); + await adapter.connect({ port: 9222 }); + expect(await adapter.openThread('local:archived', { openTimeoutMs: 1500 })).toMatchObject({ threadId: 'local:archived', archived: true }); + expect(navigated).toBe(true); +}); + +it('reads an archived thread through app-server and exposes an MCP open operation', async () => { + const facade = new ChatGptDesktopFacade({ + connect: async () => {}, close: async () => {}, + openThread: async (threadId: string) => ({ threadId, backend: 'cdp', archived: true }), + } as unknown as ChatGptDesktopAdapter, 9222, { + readThread: async ({ threadId }: { threadId: string }) => ({ threadId, backend: 'app-server', turns: [], limit: 100, full: false, complete: true }), + } as never); + expect(await facade.readThread({ threadId: 'local:archived' })).toMatchObject({ backend: 'app-server', complete: true }); + setChatGptDesktopAdapterForTests(facade); + expect(await openThreadOperation(openThreadSchema.parse({ threadId: 'local:archived' }))).toMatchObject({ archived: true, exitCode: 0 }); + expect((await listMcpSurface({ server: 'grok-bot' })).tools).toContain('chatgpt_desktop_open_thread'); + const opened = await invokeMcpTool('chatgpt_desktop_open_thread', { server: 'grok-bot', input: { threadId: 'local:archived' } }); + expect(opened.isError).toBe(false); +}); + +it('rejects archived send with a specific code and unarchives only on explicit opt-in', async () => { + let archived = true; + let unarchived = 0; + let sent = 0; + const facade = new ChatGptDesktopFacade({ + connect: async () => {}, close: async () => {}, + sendMessage: async ({ threadId }: { threadId?: string }) => { + if (archived) throw new ArchivedThreadError(threadId!); + sent++; + return { threadId: threadId!, backend: 'cdp', delivery: 'accepted', experimental: false }; + }, + } as unknown as ChatGptDesktopAdapter, 9222, { + unarchiveThread: async () => { unarchived++; archived = false; }, + } as never); + setChatGptDesktopAdapterForTests(facade); + expect(await sendOperation(sendSchema.parse({ threadId: 'local:archived', text: 'hello' }))).toMatchObject({ + code: 'ARCHIVED_THREAD', reason: 'archived-thread', delivery: 'rejected', exitCode: 1, + }); + expect([unarchived, sent]).toEqual([0, 0]); + expect(await sendOperation(sendSchema.parse({ threadId: 'local:archived', text: 'hello', unarchive: true }))).toMatchObject({ + delivery: 'accepted', exitCode: 0, + }); + expect([unarchived, sent]).toEqual([1, 1]); + expect(() => sendSchema.parse({ text: 'new chat', unarchive: true })).toThrow('unarchive requires an existing threadId'); + expect(() => sendSchema.parse({ text: 'ambiguous', threadId: 'local:existing', project: 'core' })).toThrow('project is only for a new thread'); +}); + +it('calls thread/unarchive with the bare id and validates its response', async () => { + const bridge = await import('../../src/core/codex-bridge.js'); + const calls: Array<[string, unknown]> = []; + rstest.spyOn(bridge, 'openCodexSession').mockResolvedValue({ client: { + close() {}, + async request(method: string, params: unknown) { calls.push([method, params]); return { thread: { id: 'archived' } }; }, + } } as never); + await appServerUnarchiveThread('local:archived'); + expect(calls).toEqual([['thread/unarchive', { threadId: 'archived' }]]); +}); + +it('rejects an unarchive response for another thread before retrying a send', async () => { + const bridge = await import('../../src/core/codex-bridge.js'); + rstest.spyOn(bridge, 'openCodexSession').mockResolvedValue({ client: { + close() {}, async request() { return { thread: { id: 'wrong-thread' } }; }, + } } as never); + await expect(appServerUnarchiveThread('local:archived')).rejects.toThrow('returned no thread'); +}); + +it('returns a durable id after one new-thread-in-project send while preserving the temporary id', async () => { + let submitted = false; + const events: string[] = []; + mockCdp((expression) => { + if (expression.includes('projectSel')) return { ok: true, via: 'project', hoverX: 8, hoverY: 10 }; + if (expression.includes('getComputedStyle')) return { x: 12, y: 14, visible: true }; + if (expression === LOADING_TASK_GONE_EXPRESSION) return true; + if (expression === CONVERSATION_ID_EXPRESSION) return submitted ? 'durable-conversation' : ''; + if (expression === LIST_THREADS_EXPRESSION) return [{ threadId: 'local:client-new-thread:temporary', title: 'new', selected: true, pinned: false, kind: 'local' }]; + if (expression === REPLY_STATE_EXPRESSION) return { stopVisible: false, finalAssistantCount: 0, conversationId: '', reply: '', lastTurnKey: 'before' }; + if (expression === FOCUS_COMPOSER_EXPRESSION) return { ok: true }; + if (expression.includes('return Boolean(composer')) return true; + return false; + }, (method, params) => { + if (method === 'Input.dispatchMouseEvent' || method === 'Input.dispatchKeyEvent') events.push(String(params?.type)); + if (method === 'Input.dispatchKeyEvent' && params?.type === 'keyUp') submitted = true; + }); + const adapter = new CdpChatGptDesktopAdapter(); + await adapter.connect({ port: 9222 }); + const receipt = await adapter.sendMessage({ text: 'one message', project: 'core', openTimeoutMs: 1000 }); + expect(receipt).toMatchObject({ + delivery: 'accepted', threadId: 'local:durable-conversation', conversationId: 'durable-conversation', + temporaryThreadId: 'local:client-new-thread:temporary', project: 'core', + }); + expect(events.filter((event) => event === 'mousePressed')).toHaveLength(1); + expect(events.filter((event) => event === 'keyUp')).toHaveLength(1); +}); + +it('passes the dynamic project filter through the MCP list contract', async () => { + const calls: string[] = []; + setChatGptDesktopAdapterForTests({ + connect: async () => {}, close: async () => {}, + listThreads: async (options: { project?: string }) => { + calls.push(options.project!); + return { backend: 'app-server', limit: 50, threads: [] }; + }, + } as unknown as ChatGptDesktopAdapter); + expect(await listThreadsOperation(listThreadsSchema.parse({ project: 'core' }))).toMatchObject({ exitCode: 0 }); + expect(calls).toEqual(['core']); +}); + +it('selects the generic New chat action when no project is supplied', () => { + let clicked = 0; + const document = { querySelectorAll: () => [{ textContent: 'New chat', click: () => { clicked++; } }] }; + const result = new Function('document', `return ${startNewChatExpression()}`)(document); + expect(result).toEqual({ ok: true, via: 'fallback' }); + expect(clicked).toBe(1); +}); + +it('returns a typed draft error before any text insertion', async () => { + const session = { evaluate: async () => ({ ok: false, error: 'composer-has-draft' }) }; + await expect(focusComposer(session as never, 'page')).rejects.toMatchObject({ + code: 'COMPOSER_HAS_DRAFT', reason: 'composer-has-draft', delivery: 'rejected', + }); + setChatGptDesktopAdapterForTests({ connect: async () => {}, close: async () => {}, + sendMessage: async () => { throw new ComposerDraftError(); } } as unknown as ChatGptDesktopAdapter); + expect(await sendOperation(sendSchema.parse({ text: 'do not replace draft' }))).toMatchObject({ + code: 'COMPOSER_HAS_DRAFT', reason: 'composer-has-draft', exitCode: 1, + }); +}); diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index bdb6edf..9b51797 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -19,6 +19,7 @@ import { ChatGptDesktopFacade } from '../../src/core/chatgpt-desktop/facade.js'; const desktopTools = [ 'chatgpt_desktop_list_hosts', 'chatgpt_desktop_list_threads', + 'chatgpt_desktop_open_thread', 'chatgpt_desktop_read_thread', 'chatgpt_desktop_search_threads', 'chatgpt_desktop_send', diff --git a/tests/route-unit/tools.test.ts b/tests/route-unit/tools.test.ts index bfe9d43..857f470 100644 --- a/tests/route-unit/tools.test.ts +++ b/tests/route-unit/tools.test.ts @@ -133,7 +133,7 @@ beforeEach(() => { describe('grok-bot MCP server', () => { it('registers messaging, conversation and managed bridge tools', async () => { const surface = await listMcpSurface({ server: 'grok-bot' }); - expect([...surface.tools].sort()).toEqual(['chatgpt_desktop_list_hosts', 'chatgpt_desktop_list_threads', 'chatgpt_desktop_read_thread', 'chatgpt_desktop_search_threads', 'chatgpt_desktop_send', 'chatgpt_desktop_status', 'chatgpt_desktop_wait_reply', 'claude_send', 'codex_send', 'codex_threads', 'codex_wait', 'codex_watch', 'gbot_bridge_start', 'gbot_bridge_status', 'gbot_bridge_stop', 'gbot_codex_respond', 'gbot_grok_approvals', 'gbot_grok_respond', 'gbot_send', 'gbot_thread']); + expect([...surface.tools].sort()).toEqual(['chatgpt_desktop_list_hosts', 'chatgpt_desktop_list_threads', 'chatgpt_desktop_open_thread', 'chatgpt_desktop_read_thread', 'chatgpt_desktop_search_threads', 'chatgpt_desktop_send', 'chatgpt_desktop_status', 'chatgpt_desktop_wait_reply', 'claude_send', 'codex_send', 'codex_threads', 'codex_wait', 'codex_watch', 'gbot_bridge_start', 'gbot_bridge_status', 'gbot_bridge_stop', 'gbot_codex_respond', 'gbot_grok_approvals', 'gbot_grok_respond', 'gbot_send', 'gbot_thread']); }); it('lists and responds to an exact current Grok approval through the native API', async () => { From 8e0cde22f6af0a409961264d5901d29933892b28 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 28 Sep 2026 21:25:07 -0700 Subject: [PATCH 24/26] fix: page ChatGPT Desktop MCP results below document cap --- .changeset/desktop-e2e-reliability.md | 2 + artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 562 ++++++++++++++--- artifact/bin/gbot.mjs | 578 ++++++++++++++--- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 580 +++++++++++++++--- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 580 +++++++++++++++--- artifact/skills/chatgpt-desktop/SKILL.md | 16 +- docs/chatgpt-desktop-cdp.md | 11 +- src/cli/chatgpt-desktop/read.tsx | 2 + src/cli/chatgpt-desktop/search.tsx | 2 + src/core/chatgpt-desktop/adapter.ts | 2 + .../chatgpt-desktop/app-server-fallback.ts | 260 ++++++-- src/core/chatgpt-desktop/facade.ts | 52 +- src/core/chatgpt-desktop/payload-budget.ts | 67 ++ src/core/chatgpt-desktop/routes.ts | 4 + src/core/chatgpt-desktop/types.ts | 19 + .../tools/chatgpt_desktop_list_threads.tsx | 2 +- .../tools/chatgpt_desktop_read_thread.tsx | 3 +- .../tools/chatgpt_desktop_search_threads.tsx | 3 +- src/skills/chatgpt-desktop/SKILL.md | 16 +- .../chatgpt-desktop-e2e-regressions.test.ts | 108 +++- 22 files changed, 2475 insertions(+), 398 deletions(-) create mode 100644 src/core/chatgpt-desktop/payload-budget.ts diff --git a/.changeset/desktop-e2e-reliability.md b/.changeset/desktop-e2e-reliability.md index 38a3250..0ae216a 100644 --- a/.changeset/desktop-e2e-reliability.md +++ b/.changeset/desktop-e2e-reliability.md @@ -3,3 +3,5 @@ --- Fix ChatGPT Desktop host discovery, bounded thread reads and searches, list pagination, CDP navigation and project clicks, status reachability, and result provenance. Add complete MCP and skill guidance, project filters, archived-thread reads and explicit unarchive-on-send support. + +Keep MCP Desktop results below the Agent Bundle document cap with resumable, lossless read fragments and byte-bounded list/search pages. Compact display titles while matching search against full titles, and align remote host counts with filtered inventory. diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index 2b1ddc4..a01f1d2 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"ed957e4c740861191c60d07b4e0b664c3a0894b9999dd16a14577cd86de23c3e"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"b4788c931e14fe9472988d847ff58c09a0e3ea6963a12192eaf49e46687fb878"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"c477b441f64327117257b27c3b4fa31431e647bfd8806bb806b64a6df42453c5"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"dbbe31470fff7f20f3298d84e278e33fc3bc3c16813904a8b250f601a213ff03"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"4c189f7e866020f7e9265ce684da2d47a0f75feabc9a5c1d6f60098c31924064"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"67c626d501a2629651c731fc10c7c8f93a0fa22457c43b1c37cb4b96a23a51e6"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"08428b576904506e3e8e3bd01634af6041084ed109aa2142227ee1ad45ec0b0d"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"9bebbd0df8ef8de086a36ce7af926404a284de8241e68149826635bd63ca076d"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"0398f5eca28e5372125070294a7ad857287def2a613c7f16d5ac3601b516d90f"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"4c189f7e866020f7e9265ce684da2d47a0f75feabc9a5c1d6f60098c31924064"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 164291f..f22106f 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"0bf417d16a1274518c81ab4fac1b5894661407b0a2f7811cb61d0397ff0b08d6","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"71722c08f258cdb5ffb1720702c5aa9727816abb19c16d2d3b88a608506833be","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/desktop-e2e-reliability.md","sha256":"471d89f0ba5e7be136121f52aaf404c26fa6532a67409928ab3e2c69bcd2cd02"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"30aaeac24084f0a642d811aa493fc51b0fd3eddff322d359c39c573d8394ff3e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"79cfd378c2c35c51d021d1d91c9c21b26479eb7a0f99d756cdc08627e90c5df3"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"a322d4cfa34f3a2603c4233c13a8e47be4b939bc5d4d9dff46a757b2289665dc"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"91c4bf8292dea3e2066272c90f36a2882ab8b9e5bca004c2c21a68d5aaea083c"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"b801a028980e60fe37dca56e86887a1e2b0b8ce80ce77b379e7375d2e4544d5e"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"d0a33935d992af349c52ef448622da5e460b4af1a9474aac60994295245b43ad"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"a8affca89c97739995976fed02bc1432abe6f3f5beba11df6dd5e1eca044af1c"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"d20d44e1bed831eeed6e82afaac60c3e7b5d1b7753c1ec4611d76e12dbe51a46"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"e8712876dc3dc28e5bd687191400b8f593f0711588e23bd8f378fabc7f7f970a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"95322209490160d04fc52a4dfa43f2691b4c4720a7121a3f3686c9f7eb4fbbb8"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"2ec693a70f8d004e0c9ae5abb24d49b31d8c49d64dc2b96037cc32e80de3199d"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"27bbd41043d0f07bcff9825f9a85d85d216663ec98781dd38f1a54c5a3352a15"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"591e6968c008cc75827da94b91c0ea15e573640876814e35e2470342dc8bccf9"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"ed93418ff5d2bb51016783e7b0a458805e709b212974a66be804ddb9f7038033"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"824191e3c4189dcc4d68e846a8f147f91714dbbb93fdbbcbb497c0e4681846c6"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"029ed893a93f9e3660235df93eece60cbb8af5b7aba37ab3d0d677e418489895"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"d398fd4a1ecff32c58084a9e1c6266e8f6cf2db7ef29777a44d43e2ef0196ddd"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"52565007799e98c3bff4297287d8e53005e285a95bab9e4e4d0a088bded4fa8e"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"f4d5e0377cdb7297754d3220c1935fc65bfb5f605b3bc0f15f5ff328f0ce3b63"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"86334421686350ea044fb1160c19b6f5889425feb78fd608675feb8137492090"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"568ad7621546d422a7f7227b429f80bea8a8e2fb5211f1c8cc1f9ced7651d2bc"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","sha256":"b415d5bd303693649abae96b6b9d2920d29c797f5367ae8fbb2b62b635528e37"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"6b51a60a6f7bfeb7fb3882661035137b44cb3eaf6895560e7a1e53a4c8fd6d0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"71070b1734fc4ae1a48ec5878a05bdf5741785111ba4ca1f8af72f0d96734da6"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"cf1cb83c76bb46da6245fe447f811ab6f9a2d4b0b94f21d8fbea97ac324714b1"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"681e50ae6c7d3a04a76ad8eadf865ab9d793b5eb3c78f961a42d0902adacc306"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"2786b62ff2a1a4e68229199935ac63c15614a0f0bdbef74b2d06e0c405516272"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/chatgpt-desktop/SKILL.md","sha256":"ee23320518e1b8144974d26ef43d96e2de302aa413d2b298bfcd65a2c8a85433"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"cdeb0f18c938e13facf467c1b4364394ed799c87b2d4b4566508c527efc6bef4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"a869553b1f299db8c7ddf6a5e732e50df49d7ecc91aaffddd0d6b3e54ee38578"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts","sha256":"1a5da468713ff765dee4a8324a68d5952621fee5d8b817859e2b56202e579edf"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-mcp-followup.test.ts","sha256":"83c8f33a4c5e1243e353163d864e1fdd2cf0e6564ac5ac71366f01efec952398"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"208dfdea18ccc408a279666a521d2f70fdce9bdaf28f86bc5d053f7ad09a7dd2"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"88904d9d13f2449270ab3275aba933019aae6579d75a74621cdf936cd5a1f959"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"c5bb9ab56b7806fcc899df9466645f1eeed8a3cee92a95506d8efeb640018c84"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/chatgpt-desktop/SKILL.md","sourceInputs":["src/skills/chatgpt-desktop/SKILL.md"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22276,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"bb563d8ce6554a02e5de4706a24aa0c7c1e9c6e4c113547559e29f352bbea07d"},{"bytes":1540128,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"ed957e4c740861191c60d07b4e0b664c3a0894b9999dd16a14577cd86de23c3e"},{"bytes":2406223,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"b4788c931e14fe9472988d847ff58c09a0e3ea6963a12192eaf49e46687fb878"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1467923,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"c477b441f64327117257b27c3b4fa31431e647bfd8806bb806b64a6df42453c5"},{"bytes":3294851,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"dbbe31470fff7f20f3298d84e278e33fc3bc3c16813904a8b250f601a213ff03"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1299066,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"4c189f7e866020f7e9265ce684da2d47a0f75feabc9a5c1d6f60098c31924064"},{"bytes":3691,"kind":"copy","path":"skills/chatgpt-desktop/SKILL.md","sha256":"ee23320518e1b8144974d26ef43d96e2de302aa413d2b298bfcd65a2c8a85433"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Recent default 100; full default 2000","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false},{"description":"Explicitly unarchive an existing archived thread before sending.","key":"unarchive","kind":"boolean","option":"unarchive","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a previous page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_open_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"24078e6fa9b1d6694669ef83b935343f6857d87497e6817555ae4184e11d5da3","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover local, remote-control environment ids, managed SSH hosts, and modelProvider ids. hostName is null when Desktop has no real display name. Use hostId or label in list/search filters; remote thread ids must be read on the owning host. warnings report provider discovery failures.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List Desktop threads, then pass nextCursor as cursor until null. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","description":"Navigate Desktop to an existing local: or bare conversation id, even when the row is absent from the sidebar. Archived routes return archived:true without unarchiving; read them with chatgpt_desktop_read_thread. A remote-control id is owned by its hostId and cannot be opened on this Mac. CDP_UNREACHABLE means Desktop must be reachable locally.","id":"tool:grok-bot/chatgpt_desktop_open_thread","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Recent defaults to 100 turns; full pages up to 2000 from the start. Archived threads remain readable. complete:false means partial history; warnings preserve app-server/frame errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search Desktop thread metadata by case-insensitive substring. Dynamic hostId/hostName, modelProvider, and project filters apply. Search scans bounded app-server pages and reports warnings if incomplete; use list_threads cursor for exhaustive paging. Remote results identify hostId and cannot be read on this Mac.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Check local ChatGPT Desktop CDP before send, wait, or open. reachable:false and exitCode:1 mean CDP is down even if appServerFallback.reachable is true; list/search/read may still work through app-server. There is no remote CDP transport.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"After chatgpt_desktop_send, wait for the selected Desktop reply over CDP. Accept the returned durable local: or the temporary local:client-new-thread:* while selected; omit threadId only when staying on the same selected chat. Returns reply, durable threadId and conversationId. timeout is not proof the send failed; CDP_UNREACHABLE requires Desktop recovery. Remote ids must be handled on their hostId.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.1"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"d4c541520ff70aa788ed52d6012548a4feb7b69196826a7b3e4812eb8d0c3e40","packageName":"grok-bot-cli","packageVersion":"0.10.1","revision":"fb7b645c16c8186a09fae9b549e73ff316624b2317a7b87b07ba4f0f3fbd0ad0","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/desktop-e2e-reliability.md","sha256":"ebb912d56ba3321df13a9d611780129af8f4c264dbc5e841df6c1a8a838dfc10"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".changeset/rstest-core-0-12.md","sha256":"59333ce95dc5d40b5dd7d024eeeade7961e348584aebbafabeeb77978c3905ce"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"30aaeac24084f0a642d811aa493fc51b0fd3eddff322d359c39c573d8394ff3e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"759ad2e3ef6535b52e147a358f7ee61c8225e0b81d75e4885a28acd018c69dab"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"153f42cdf9d8e433cb19c2e9842d75333f6afbdf2ce32d48f87829eedcf2247a"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"2c3f292e39582f1aa431aeb2a0732c433bb167be9a6d1df2a04a8064cce47e76"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"ec505510b9895eca2afdcc2b4b2eba8a90e33468de1a47ad2aeb610dbdb601db"},{"executable":false,"path":"README.md","sha256":"f1a0e98b6a263785700d89b37c57fb23e469d34fd6870d32e61a6ad8ceccb7ad"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"11c86f604c2ee405f7544394db60ee1b36917d0b90769d441fcd361b5f0fe038"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"0dc3acdea178ff14d6c1c4b8b3bf1e18af47984f63b8ed8c41483e4da4b72f08"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"b801a028980e60fe37dca56e86887a1e2b0b8ce80ce77b379e7375d2e4544d5e"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"d0a33935d992af349c52ef448622da5e460b4af1a9474aac60994295245b43ad"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"6848001878471439bcc35a2c40010ecf0e57e61087879b1f4d6abb1be19e7924"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"c2ec45e5907e27ff0ab1885eceb2d62c33485b8d61f44ef871a24e7a7e8473ca"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5a0a4f2cea9f1fc1a739c534aed3979c28e0bd9c057b8475e6251974ad44ed7a"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"60c6d7bb5ad2ae3aab9b9af86eb7697cbd7eda7dbcf01dba0b88356bd1855f78"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"e8712876dc3dc28e5bd687191400b8f593f0711588e23bd8f378fabc7f7f970a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"95322209490160d04fc52a4dfa43f2691b4c4720a7121a3f3686c9f7eb4fbbb8"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"2ec693a70f8d004e0c9ae5abb24d49b31d8c49d64dc2b96037cc32e80de3199d"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"c2900c9402cc977b8667269fe23c843162820f78d3925fd56176b868c9d59505"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"591e6968c008cc75827da94b91c0ea15e573640876814e35e2470342dc8bccf9"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/payload-budget.ts","sha256":"89410474315b3769bad58d3ab61999e169410b7d1fdc20819efb4ee9c82fe1ac"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"ed93418ff5d2bb51016783e7b0a458805e709b212974a66be804ddb9f7038033"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"ccf8cde780da6e6e03f11e4dcc0d9d6bc4a6a3fd20d3210e74f0217e3660b7e1"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"75a24433b127d3b5dfee43f4abdef7e33b43e94b55fcab5877ad20fba94c1913"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"d398fd4a1ecff32c58084a9e1c6266e8f6cf2db7ef29777a44d43e2ef0196ddd"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"a59994ae25e6133f2e6bf0c7a6413008780a0ad2781336b6826a131eb3416ee1"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"52565007799e98c3bff4297287d8e53005e285a95bab9e4e4d0a088bded4fa8e"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"f4d5e0377cdb7297754d3220c1935fc65bfb5f605b3bc0f15f5ff328f0ce3b63"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"827f4d209c0681d4ed973ef41e0b2264e64c38a43aecef279efe53713b129f0e"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"c6ffc479436282348a491e0f18b1b0e2944deb0619e025484ab6a8d25ec3c2c5"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"0e00c45a87cea0af5faa7e21a681371708e88140659747bd8a068a8dd10eccc8"},{"executable":false,"path":"src/core/relay/state.js","sha256":"f803d955619387306852a2965a75afc26804a982309dd04c9564e5ae31d638d2"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"6cd01eec270bce303134ee0ab8a50f721988aaac21ae6c6e6c7cdb05b82a9bf4"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"86334421686350ea044fb1160c19b6f5889425feb78fd608675feb8137492090"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"302cb90f620e488d48e11dc7fbe5676d711fd6dcebcab0fa6b387e3ba4221c23"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","sha256":"b415d5bd303693649abae96b6b9d2920d29c797f5367ae8fbb2b62b635528e37"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"6adc4318f4b6c90b1d3970046266197348f79757c0d52ffe991d6338eb1fed6c"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"1d50db88cf7d06a74524c8937ed9045eaaf2560f6766d6c411b3bb55575d1d3f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"cf1cb83c76bb46da6245fe447f811ab6f9a2d4b0b94f21d8fbea97ac324714b1"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"681e50ae6c7d3a04a76ad8eadf865ab9d793b5eb3c78f961a42d0902adacc306"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"2786b62ff2a1a4e68229199935ac63c15614a0f0bdbef74b2d06e0c405516272"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"a143cdfe89059f2226a3ca4611709831f190d001f5bf213b235068dd2860ce7b"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"dcf5caf14c053f69e04665897261e1d889920e750ade7c0478f19407e863ff29"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/chatgpt-desktop/SKILL.md","sha256":"3fa1ad5023fbd000b7164e45d749951c7acc16f79933a945823169ae278d2c92"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"cdeb0f18c938e13facf467c1b4364394ed799c87b2d4b4566508c527efc6bef4"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"c11559a8c0206982d506bcb018f9421085b8fb17ed82a6b255faf276a30f3a69"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"a869553b1f299db8c7ddf6a5e732e50df49d7ecc91aaffddd0d6b3e54ee38578"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a3e7e4a63ec82014eec83b91d003ac89295d1f0ac3807bcf39071e4334bf2680"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts","sha256":"27c7cabcbc6fea9235aff50674ad564b7aa8a087b1a2257db330131253f7b743"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-mcp-followup.test.ts","sha256":"83c8f33a4c5e1243e353163d864e1fdd2cf0e6564ac5ac71366f01efec952398"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"208dfdea18ccc408a279666a521d2f70fdce9bdaf28f86bc5d053f7ad09a7dd2"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"88904d9d13f2449270ab3275aba933019aae6579d75a74621cdf936cd5a1f959"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"c5bb9ab56b7806fcc899df9466645f1eeed8a3cee92a95506d8efeb640018c84"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/chatgpt-desktop/SKILL.md","sourceInputs":["src/skills/chatgpt-desktop/SKILL.md"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"33951579275959e7353959d75cfb0663b15c4b48c9530c91e6bafcb9289e5027"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"ddb3bdc074c2850d13739586648b5c8fb93373feeca64256a320057e77f245aa"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"1967a6e1ea7841a1a3ba746052db4e7a49ccab5f25b5164f7e6ef6b017aa1940"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":669,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"ba82c4ae8bb554e4921a2995db479e874067afa291341d2cf6afefdfb4f4cea8"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22276,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"b2a105c2f7993bbdff30a73243a506da9cbbd4fb6b43f29fa3bbf307948a0c5e"},{"bytes":1560807,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"67c626d501a2629651c731fc10c7c8f93a0fa22457c43b1c37cb4b96a23a51e6"},{"bytes":2427714,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"08428b576904506e3e8e3bd01634af6041084ed109aa2142227ee1ad45ec0b0d"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"c24e3c7e7cfef3e263bc4567146597ddd7905687011a5cc642595a65e2f0999f"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"5c9d631765a1f1f65748ede74697b6a1c36ec898a4b73ec7ff0045fd51ef40b2"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270072,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"b4a33c03dd18dd87e5e0bce860a555ed7d1aa26db170a8c77ef3110d09c6b36a"},{"bytes":1489530,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"9bebbd0df8ef8de086a36ce7af926404a284de8241e68149826635bd63ca076d"},{"bytes":3316522,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"0398f5eca28e5372125070294a7ad857287def2a613c7f16d5ac3601b516d90f"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"fe9e41cac051240703da260ef59cde755135de32174eaf745532a2740fb5b29f"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1299066,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"4c189f7e866020f7e9265ce684da2d47a0f75feabc9a5c1d6f60098c31924064"},{"bytes":4168,"kind":"copy","path":"skills/chatgpt-desktop/SKILL.md","sha256":"3fa1ad5023fbd000b7164e45d749951c7acc16f79933a945823169ae278d2c92"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"description":"Opaque nextCursor from the prior read page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Recent default 100; full default 2000","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a prior search page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false},{"description":"Explicitly unarchive an existing archived thread before sending.","key":"unarchive","kind":"boolean","option":"unarchive","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a previous page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page","type":"string"},"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a prior search page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page","type":"string"},"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a prior search page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_open_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page. Keep threadId and full unchanged.","type":"string"},"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the previous search page; keep query and filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"a5d0cdc32dfee35503cb22916baff9851f16c2cd8a79d14d3ecc250b20213def","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover local, remote-control environment ids, managed SSH hosts, and modelProvider ids. hostName is null when Desktop has no real display name. Use hostId or label in list/search filters; remote thread ids must be read on the owning host. warnings report provider discovery failures.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List Desktop threads, then pass nextCursor as cursor until null. Pages may stop early at the MCP byte budget. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","description":"Navigate Desktop to an existing local: or bare conversation id, even when the row is absent from the sidebar. Archived routes return archived:true without unarchiving; read them with chatgpt_desktop_read_thread. A remote-control id is owned by its hostId and cannot be opened on this Mac. CDP_UNREACHABLE means Desktop must be reachable locally.","id":"tool:grok-bot/chatgpt_desktop_open_thread","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Pass nextCursor back as cursor with the same threadId/full mode until complete:true. Pages stop at a byte budget; oversized turns use ordered continuation fragments with stable turnKey and field offsets, without dropping text. Archived threads remain readable. Warnings explain partial pages or app-server errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page. Keep threadId and full unchanged.","type":"string"},"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search full Desktop thread metadata by case-insensitive substring. Display titles are capped at 200 characters with titleTruncated:true. Pass nextCursor as cursor with unchanged query and filters to retrieve all matches. Dynamic hostId/hostName, modelProvider, and project filters apply. Remote results identify hostId and cannot be read on this Mac.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the previous search page; keep query and filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Check local ChatGPT Desktop CDP before send, wait, or open. reachable:false and exitCode:1 mean CDP is down even if appServerFallback.reachable is true; list/search/read may still work through app-server. There is no remote CDP transport.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"After chatgpt_desktop_send, wait for the selected Desktop reply over CDP. Accept the returned durable local: or the temporary local:client-new-thread:* while selected; omit threadId only when staying on the same selected chat. Returns reply, durable threadId and conversationId. timeout is not proof the send failed; CDP_UNREACHABLE requires Desktop recovery. Remote ids must be handled on their hostId.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index 2d7c785..b8ecf66 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -8674,6 +8674,10 @@ var __webpack_modules__ = { default: false, type: 'boolean' }, + cursor: { + description: 'Opaque nextCursor from the prior read page', + type: 'string' + }, limit: { description: 'Recent default 100; full default 2000', type: 'number' @@ -8700,6 +8704,7 @@ var __webpack_modules__ = { }; const inputSchema = zod__rspack_import_2.Ikc({ full: zod__rspack_import_2.zMY().default(false), + cursor: zod__rspack_import_2.YjP().min(1).max(4096).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(2000).optional(), openTimeoutMs: zod__rspack_import_2.aig().int().min(1).max(600000).default(90000), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), @@ -8762,6 +8767,10 @@ var __webpack_modules__ = { description: 'Max matches (1-200)', type: 'number' }, + cursor: { + description: 'Opaque nextCursor from a prior search page', + type: 'string' + }, modelProvider: { description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' @@ -8788,6 +8797,7 @@ var __webpack_modules__ = { groupBy: zod__rspack_import_2.euz('host').optional(), host: zod__rspack_import_2.YjP().min(1).max(256).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), + cursor: zod__rspack_import_2.YjP().min(1).max(4096).optional(), modelProvider: zod__rspack_import_2.YjP().min(1).max(256).optional(), project: zod__rspack_import_2.YjP().min(1).max(256).optional(), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), @@ -11294,64 +11304,173 @@ var __webpack_modules__ = { var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _remote_threads_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _payload_budget_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + const LIST_PAGE_PREFIX = 'desktop-list-v1:'; + const SEARCH_PAGE_PREFIX = 'desktop-search-v1:'; + const READ_PAGE_PREFIX = 'desktop-read-v1:'; async function appServerListThreads({ limit = 50, cursor, modelProviders = [] } = {}) { + let sourceCursor = cursor; + let skip = 0; + let fetchLimit = Math.min(limit, 25); + if (cursor?.startsWith(LIST_PAGE_PREFIX)) { + const state = (0, _payload_budget_js__rspack_import_4.i3)(LIST_PAGE_PREFIX, cursor); + if (!Number.isSafeInteger(state.skip) || state.skip < 1 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || state.cursor !== null && typeof state.cursor !== 'string') { + throw new Error('Invalid ChatGPT Desktop list page cursor'); + } + sourceCursor = state.cursor ?? undefined; + skip = state.skip; + fetchLimit = state.fetchLimit; + } const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit, - cursor, + limit: fetchLimit, + cursor: sourceCursor, modelProviders }); - return { + if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); + const base = { backend: 'app-server', - limit: out.limit, - nextCursor: out.nextCursor ?? null, - threads: out.threads.map(mapListedThread), + limit, modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; + const threads = []; + let consumed = skip; + for (const raw of out.threads.slice(skip)){ + if (threads.length >= limit) break; + let row = (0, _payload_budget_js__rspack_import_4.eX)(mapListedThread(raw)); + const probe = { + ...base, + threads: [ + ...threads, + row + ], + nextCursor: LIST_PAGE_PREFIX, + exitCode: 0 + }; + if ((0, _payload_budget_js__rspack_import_4.sQ)(probe) > 614400) { + if (threads.length) break; + row = (0, _payload_budget_js__rspack_import_4.MH)(row); + if ((0, _payload_budget_js__rspack_import_4.sQ)({ + ...base, + threads: [ + row + ], + nextCursor: LIST_PAGE_PREFIX, + exitCode: 0 + }) > 614400) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + threads.push(row); + consumed++; + } + const nextCursor = consumed < out.threads.length ? (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { + cursor: sourceCursor ?? null, + skip: consumed, + fetchLimit + }) : out.nextCursor ?? null; + return { + ...base, + threads, + nextCursor, + ...consumed < out.threads.length ? { + warnings: [ + 'List page stopped at the MCP byte budget; continue with nextCursor' + ] + } : {} + }; } - async function appServerSearchThreads({ query, limit = 50, modelProviders = [], project }) { + async function appServerSearchThreads({ query, limit = 50, cursor, modelProviders = [], project }) { const needle = query.trim().toLowerCase(); if (!needle) { return appServerListThreads({ limit, + cursor, modelProviders }); } const matched = []; - let cursor; - let exhausted = false; - for(let page = 0; page < 400 && matched.length < limit; page++){ + let sourceCursor; + let skip = 0; + if (cursor) { + const state = (0, _payload_budget_js__rspack_import_4.i3)(SEARCH_PAGE_PREFIX, cursor); + if (state.query !== query || state.project !== project || JSON.stringify(state.modelProviders) !== JSON.stringify(modelProviders) || !Number.isSafeInteger(state.skip) || state.skip < 0) { + throw new Error('Search cursor does not match this query and its filters'); + } + sourceCursor = state.cursor ?? undefined; + skip = state.skip; + } + const pageCursor = (rpcCursor, offset)=>(0, _payload_budget_js__rspack_import_4.oI)(SEARCH_PAGE_PREFIX, { + cursor: rpcCursor ?? null, + skip: offset, + query, + project, + modelProviders + }); + const base = { + backend: 'app-server', + limit, + query, + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined + }; + for(let page = 0; page < 400; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit: 25, - cursor, + cursor: sourceCursor, modelProviders }); - for (const thread of out.threads){ - const mapped = mapListedThread(thread); - if (threadMatchesQuery(mapped, needle) && (!project || [ + if (skip > out.threads.length) throw new Error('ChatGPT Desktop search cursor is stale'); + for(let index = skip; index < out.threads.length; index++){ + const mapped = mapListedThread(out.threads[index]); + if (!threadMatchesQuery(mapped, needle) || project && ![ mapped.project, mapped.projectId - ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase())))) matched.push(mapped); - if (matched.length >= limit) break; - } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') { - exhausted = true; - break; + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase()))) continue; + let row = (0, _payload_budget_js__rspack_import_4.eX)(mapped); + if ((0, _payload_budget_js__rspack_import_4.sQ)({ + ...base, + threads: [ + ...matched, + row + ], + nextCursor: SEARCH_PAGE_PREFIX, + exitCode: 0 + }) > 614400) { + if (matched.length) return { + ...base, + threads: matched, + nextCursor: pageCursor(sourceCursor, index), + warnings: [ + 'Search page stopped at the MCP byte budget; continue with nextCursor' + ] + }; + row = (0, _payload_budget_js__rspack_import_4.MH)(row); + } + matched.push(row); + if (matched.length >= limit) { + const nextCursor = index + 1 < out.threads.length ? pageCursor(sourceCursor, index + 1) : out.nextCursor ? pageCursor(out.nextCursor, 0) : null; + return { + ...base, + threads: matched, + nextCursor + }; + } } - cursor = out.nextCursor; + if (out.nextCursor == null) return { + ...base, + threads: matched, + nextCursor: null + }; + sourceCursor = out.nextCursor; + skip = 0; } return { - backend: 'app-server', - limit, - query, - nextCursor: null, - threads: matched.slice(0, limit), - modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, - ...!exhausted && matched.length < limit ? { - warnings: [ - 'Search stopped after 400 app-server pages; results may be incomplete' - ] - } : {} + ...base, + threads: matched, + nextCursor: pageCursor(sourceCursor, 0), + warnings: [ + 'Search stopped after 400 app-server pages; continue with nextCursor' + ] }; } async function discoverModelProviders() { @@ -11386,7 +11505,7 @@ var __webpack_modules__ = { complete }; } - async function appServerReadThread({ threadId, limit, full = false }) { + async function appServerReadThread({ threadId, limit, full = false, cursor }) { limit ??= full ? 2000 : 100; const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); @@ -11394,7 +11513,8 @@ var __webpack_modules__ = { try { return await readLocalThread(bare, { limit, - full + full, + cursor }); } catch (error) { if (isThreadNotLoaded(error) || isUnknownThread(error)) { @@ -11406,7 +11526,8 @@ var __webpack_modules__ = { try { return await readLocalThread(bare, { limit, - full + full, + cursor }); } catch (error) { throw maybeRemoteThreadError(error, bare); @@ -11426,13 +11547,15 @@ var __webpack_modules__ = { client.close(); } } - async function readLocalThread(bare, { limit, full }) { + async function readLocalThread(bare, { limit, full, cursor }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { const meta = await readThreadMetadata(client, bare); - const { turns, complete } = await listTurnsFull(client, bare, { + const { turns, complete, nextCursor } = await listTurnsFull(client, bare, { limit, - full + full, + cursor, + title: meta.title }); return { threadId: (0, _thread_ids_js__rspack_import_3.BS)(bare), @@ -11441,7 +11564,13 @@ var __webpack_modules__ = { limit, full, complete, - title: meta.title, + nextCursor, + ...complete ? {} : { + warnings: [ + 'Read page stopped before the end of the thread; continue with nextCursor to retrieve every turn and text fragment' + ] + }, + ...meta.title ? (0, _payload_budget_js__rspack_import_4.aA)(meta.title) : {}, cwd: meta.cwd, status: meta.status, modelProvider: meta.modelProvider, @@ -11523,56 +11652,200 @@ var __webpack_modules__ = { throw maybeRemoteThreadError(error, threadId); } } - async function listTurnsFull(client, threadId, { limit, full }) { - const collected = []; - let cursor; + async function listTurnsFull(client, threadId, { limit, full, cursor, title }) { + const state = cursor ? (0, _payload_budget_js__rspack_import_4.i3)(READ_PAGE_PREFIX, cursor) : null; + if (state && (state.threadId !== threadId || state.full !== full || !Number.isSafeInteger(state.skip) || state.skip < 0 || state.rpcCursor !== null && typeof state.rpcCursor !== 'string' || state.field !== undefined && ![ + 'text', + 'userText', + 'assistantText' + ].includes(state.field) || state.offset !== undefined && (!Number.isSafeInteger(state.offset) || state.offset < 0))) { + throw new Error('Read cursor does not match this thread or mode'); + } + let rpcCursor = state?.rpcCursor ?? undefined; + let skip = state?.skip ?? 0; + let fragmentField = state?.field; + let fragmentOffset = state?.offset ?? 0; let itemsView = true; let method = 'thread/turns/list'; const seen = new Set(); - let complete = false; - while(collected.length < limit){ + const turns = []; + const pageCursor = (source, index, field, offset)=>(0, _payload_budget_js__rspack_import_4.oI)(READ_PAGE_PREFIX, { + threadId, + full, + rpcCursor: source ?? null, + skip: index, + ...field ? { + field, + offset + } : {} + }); + const fits = (candidate)=>(0, _payload_budget_js__rspack_import_4.sQ)({ + threadId, + turns: [ + ...turns, + candidate + ], + backend: 'app-server', + limit, + full, + complete: false, + nextCursor: READ_PAGE_PREFIX, + title: title ? (0, _payload_budget_js__rspack_import_4.aA)(title).title : undefined, + warnings: [ + 'Read page stopped before the end of the thread; continue with nextCursor to retrieve every turn and text fragment' + ], + exitCode: 0 + }) <= 614400; + while(turns.length < limit){ let result; try { result = await client.request(method, { threadId, - limit: Math.min(10, limit - collected.length), + limit: Math.min(10, Math.max(limit - turns.length, skip + 1)), sortDirection: full ? 'asc' : 'desc', ...method === 'thread/turns/list' && itemsView ? { itemsView: 'full' } : {}, - ...cursor !== undefined ? { - cursor + ...rpcCursor !== undefined ? { + cursor: rpcCursor } : {} }); } catch (error) { const code = error?.rpc?.code; - if (collected.length === 0 && code === -32602 && itemsView) { + if (turns.length === 0 && code === -32602 && itemsView) { itemsView = false; continue; } - if (collected.length === 0 && code === -32601 && method === 'thread/turns/list') { + if (turns.length === 0 && code === -32601 && method === 'thread/turns/list') { method = 'thread/items/list'; continue; } throw maybeRemoteThreadError(error, threadId); } if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); - collected.push(...result.data); - if (result.nextCursor == null) { - complete = true; - break; + if (skip > result.data.length) throw new Error('Read cursor is stale'); + const pageTurns = normalizeTurns(result.data); + for(let index = skip; index < pageTurns.length; index++){ + const turn = pageTurns[index]; + if (!fragmentField && turns.length && !fits(turn)) { + return { + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, index) + }; + } + if (!fragmentField && fits(turn)) { + turns.push(turn); + } else { + const fields = [ + 'text', + 'userText', + 'assistantText' + ].filter((field)=>typeof turn[field] === 'string' && turn[field].length > 0); + let fieldIndex = fragmentField ? fields.indexOf(fragmentField) : 0; + if (fieldIndex < 0) throw new Error('Read fragment cursor is stale'); + for(; fieldIndex < fields.length; fieldIndex++){ + const field = fields[fieldIndex]; + const value = turn[field]; + let offset = field === fragmentField ? fragmentOffset : 0; + if (offset > value.length) throw new Error('Read fragment cursor is stale'); + while(offset < value.length){ + let size = Math.min(value.length - offset, 32768); + let fragment; + do { + let end = offset + size; + if (end < value.length && /[\uD800-\uDBFF]/u.test(value[end - 1])) end--; + const chunk = value.slice(offset, end); + fragment = { + turnKey: turn.turnKey, + role: turn.role, + text: field === 'text' ? chunk : '', + ...field === 'userText' ? { + userText: chunk + } : {}, + ...field === 'assistantText' ? { + assistantText: chunk + } : {}, + startedAt: turn.startedAt, + endedAt: turn.endedAt, + textTruncated: true, + continuation: { + field, + offsetChars: offset, + totalChars: value.length, + fieldComplete: end === value.length, + turnComplete: end === value.length && fieldIndex === fields.length - 1 + } + }; + if (fits(fragment)) { + size = end - offset; + break; + } + size = Math.floor(size / 2); + }while (size > 0); + if (size === 0) { + if (turns.length) return { + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, index, field, offset) + }; + throw new Error('Read fragment metadata exceeds the MCP result byte budget'); + } + turns.push(fragment); + offset += size; + if (turns.length >= limit || offset < value.length && !fits({ + ...fragment, + text: 'x'.repeat(32768) + })) { + return { + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, index, field, offset) + }; + } + } + } + fragmentField = undefined; + fragmentOffset = 0; + } + if (turns.length >= limit) { + const nextCursor = index + 1 < pageTurns.length ? pageCursor(rpcCursor, index + 1) : result.nextCursor ? pageCursor(result.nextCursor, 0) : null; + return { + turns: chronologicalPage(turns, full), + complete: nextCursor === null, + nextCursor + }; + } } + if (result.nextCursor == null) return { + turns: chronologicalPage(turns, full), + complete: true, + nextCursor: null + }; if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { throw new Error(`${method} returned an invalid or repeated cursor`); } seen.add(result.nextCursor); - cursor = result.nextCursor; + rpcCursor = result.nextCursor; + skip = 0; } - const turns = normalizeTurns(collected.slice(0, limit)); return { - turns: full ? turns : turns.reverse(), - complete - }; + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, skip) + }; + } + function chronologicalPage(turns, full) { + if (full) return turns; + const groups = []; + for (const turn of turns){ + const last = groups.at(-1); + if (last?.[0]?.turnKey === turn.turnKey) last.push(turn); + else groups.push([ + turn + ]); + } + return groups.reverse().flat(); } function normalizeTurns(raw) { const turns = []; @@ -12872,6 +13145,7 @@ var __webpack_modules__ = { var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); var _remote_threads_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _payload_budget_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); var _thread_ids_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, @@ -12951,7 +13225,28 @@ var __webpack_modules__ = { }); const offset = remoteOffset ?? 0; if (remoteOffset !== null || remoteInventory.threads.length >= limit) { - const page = remoteInventory.threads.slice(offset, offset + limit); + const page = []; + for (const thread of remoteInventory.threads.slice(offset, offset + limit)){ + const row = (0, _payload_budget_js__rspack_import_6.eX)(thread); + if ((0, _payload_budget_js__rspack_import_6.sQ)({ + ...remoteInventory, + threads: [ + ...page, + row + ], + nextCursor: REMOTE_PAGE_CURSOR, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost([ + ...page, + row + ]) + } : {} + }) > 614400) { + if (!page.length) throw new Error('ChatGPT Desktop remote thread row exceeds the MCP result byte budget'); + break; + } + page.push(row); + } const nextOffset = offset + page.length; const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; return { @@ -13063,16 +13358,16 @@ var __webpack_modules__ = { } const hostsSource = 'local+remote-thread-summaries-v3+managed-connections' + (cdpRows.length ? '+cdp' : ''); const remoteCounts = new Map(); - for (const thread of remotes){ - remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); - } - const remoteIds = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); - for (const thread of cdpRows){ - if (thread.location !== 'remote' || !thread.hostId) continue; - const id = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; - if (remoteIds.has(id)) continue; - remoteIds.add(id); - remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + const remoteInventory = finalizeThreadList({ + backend: cdpRows.length ? 'cdp' : 'remote-state', + limit: 10000, + threads: cdpRows.filter((thread)=>thread.location === 'remote') + }, { + limit: 10000, + remotes + }); + for (const thread of remoteInventory.threads){ + if (thread.hostId) remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); } const withCounts = [ ...byId.values() @@ -13113,10 +13408,21 @@ var __webpack_modules__ = { ]) ].sort(); return { - hosts: withCounts.map((host)=>host.hostId === 'local' ? { + hosts: withCounts.map((host)=>{ + const counted = host.hostId === 'local' ? { ...host, threadCount: localThreadCount - } : host), + } : host; + if (!counted.hostName) return counted; + const name = (0, _payload_budget_js__rspack_import_6.aA)(counted.hostName); + return { + ...counted, + hostName: name.title, + ...name.titleTruncated ? { + hostNameTruncated: true + } : {} + }; + }), hostsSource, modelProviders, modelProvidersSource, @@ -13134,25 +13440,27 @@ var __webpack_modules__ = { const appList = await this.#fallbacks.searchThreads({ query: options.query, limit, + cursor: options.cursor, modelProviders, project: options.project }); - const cdpList = await this.#tryCdpList({ + const cdpList = options.cursor ? null : await this.#tryCdpList({ limit }); const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const appMatches = new Set(appList.threads.map((thread)=>thread.threadId)); const withRemotes = finalizeThreadList(base, { limit: 10000, host, modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - remotes: this.#listRemotes() + remotes: options.cursor ? [] : this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); const filtered = { ...withRemotes, query: options.query, - threads: withRemotes.threads.filter((thread)=>threadMatchesQuery(thread, needle)) + threads: withRemotes.threads.filter((thread)=>appMatches.has(thread.threadId) || threadMatchesQuery(thread, needle)) }; const result = finalizeThreadList(filtered, { limit, @@ -13164,6 +13472,7 @@ var __webpack_modules__ = { }); return result; } catch (appError) { + if (options.cursor) throw appError; const cdpList = await this.#tryCdpList({ limit }); @@ -13198,6 +13507,7 @@ var __webpack_modules__ = { const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { + if (options.cursor) throw new Error('Temporary Desktop threads do not support read cursors'); await this.#ensureCdp(); return this.#cdp.readThread({ ...options, @@ -13209,10 +13519,12 @@ var __webpack_modules__ = { return await this.#fallbacks.readThread({ threadId: options.threadId, limit, - full + full, + cursor: options.cursor }); } catch (appError) { if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; + if (options.cursor) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; const fallback = await this.#cdp.readThread({ @@ -13404,7 +13716,7 @@ var __webpack_modules__ = { if (!projectMatches(thread, project)) return false; return true; }); - const limited = filtered.slice(0, limit); + const limited = filtered.slice(0, limit).map(_payload_budget_js__rspack_import_6.eX); const result = { backend: remotes.length ? base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' : base.backend === 'app-server' ? 'app-server+remote-state' : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend : base.backend, limit, @@ -13580,6 +13892,100 @@ var __webpack_modules__ = { jv: ()=>forceLoopbackWebSocketUrl }); }, + "./src/core/chatgpt-desktop/payload-budget.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + const DESKTOP_RESULT_BUDGET_BYTES = 600 * 1024; + const DESKTOP_THREAD_TITLE_CHARS = 200; + function serializedBytes(value) { + return Buffer.byteLength(JSON.stringify(value), 'utf8'); + } + function compact(value, maxChars) { + const normalized = value.replace(/\s+/gu, ' ').trim(); + const chars = Array.from(normalized); + return { + value: chars.slice(0, maxChars).join(''), + clipped: chars.length > maxChars + }; + } + function compactThreadRow(thread) { + const title = compact(thread.title, DESKTOP_THREAD_TITLE_CHARS); + const preview = typeof thread.preview === 'string' ? compact(thread.preview, 200) : null; + const cwd = typeof thread.cwd === 'string' ? compact(thread.cwd, 2048) : null; + const project = typeof thread.project === 'string' ? compact(thread.project, 256) : null; + const hostName = typeof thread.hostName === 'string' ? compact(thread.hostName, 256) : null; + return { + ...thread, + title: title.value, + ...title.clipped ? { + titleTruncated: true + } : {}, + ...preview ? { + preview: preview.value, + ...preview.clipped ? { + previewTruncated: true + } : {} + } : {}, + ...cwd ? { + cwd: cwd.value, + ...cwd.clipped ? { + cwdTruncated: true + } : {} + } : {}, + ...project ? { + project: project.value, + ...project.clipped ? { + projectTruncated: true + } : {} + } : {}, + ...hostName ? { + hostName: hostName.value, + ...hostName.clipped ? { + hostNameTruncated: true + } : {} + } : {} + }; + } + function compactThreadTitle(title) { + const out = compact(title, DESKTOP_THREAD_TITLE_CHARS); + return { + title: out.value, + titleTruncated: out.clipped + }; + } + function minimalThreadRow(thread) { + return { + threadId: thread.threadId, + title: compact(thread.title, DESKTOP_THREAD_TITLE_CHARS).value, + titleTruncated: true, + pinned: thread.pinned, + selected: thread.selected, + kind: thread.kind, + location: thread.location, + hostId: thread.hostId, + hostName: thread.hostName, + modelProvider: thread.modelProvider, + metadataTruncated: true + }; + } + function encodePageCursor(prefix, value) { + return prefix + Buffer.from(JSON.stringify(value)).toString('base64url'); + } + function decodePageCursor(prefix, cursor) { + if (!cursor.startsWith(prefix)) throw new Error('Invalid ChatGPT Desktop page cursor'); + try { + return JSON.parse(Buffer.from(cursor.slice(prefix.length), 'base64url').toString('utf8')); + } catch { + throw new Error('Invalid ChatGPT Desktop page cursor'); + } + } + __webpack_require__.d(__webpack_exports__, { + MH: ()=>minimalThreadRow, + aA: ()=>compactThreadTitle, + eX: ()=>compactThreadRow, + i3: ()=>decodePageCursor, + oI: ()=>encodePageCursor, + sQ: ()=>serializedBytes + }); + }, "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); @@ -14017,6 +14423,7 @@ var __webpack_modules__ = { port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), query: zod__rspack_import_4.YjP().min(1).max(512), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), project: zod__rspack_import_4.YjP().min(1).max(256).optional(), @@ -14030,6 +14437,7 @@ var __webpack_modules__ = { threadId, limit: zod__rspack_import_4.aig().int().min(1).max(2000).optional(), full: zod__rspack_import_4.zMY().default(false), + cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); const openThreadSchema = zod__rspack_import_4.Ikc({ @@ -14159,6 +14567,7 @@ var __webpack_modules__ = { return adapter.searchThreads({ query: input.query, limit: input.limit, + cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, project: input.project, @@ -14195,6 +14604,7 @@ var __webpack_modules__ = { threadId: input.threadId, limit: input.limit ?? (input.full ? 2000 : 100), full: input.full, + cursor: input.cursor, openTimeoutMs: input.openTimeoutMs })); return asResult({ diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index e0cbf75..5b7402f 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -7082,6 +7082,10 @@ var __webpack_modules__ = { default: false, type: 'boolean' }, + cursor: { + description: 'Opaque nextCursor from the prior read page', + type: 'string' + }, limit: { description: 'Recent default 100; full default 2000', type: 'number' @@ -7108,6 +7112,7 @@ var __webpack_modules__ = { }; const inputSchema = zod__rspack_import_2.Ikc({ full: zod__rspack_import_2.zMY().default(false), + cursor: zod__rspack_import_2.YjP().min(1).max(4096).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(2000).optional(), openTimeoutMs: zod__rspack_import_2.aig().int().min(1).max(600000).default(90000), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), @@ -7170,6 +7175,10 @@ var __webpack_modules__ = { description: 'Max matches (1-200)', type: 'number' }, + cursor: { + description: 'Opaque nextCursor from a prior search page', + type: 'string' + }, modelProvider: { description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', type: 'string' @@ -7196,6 +7205,7 @@ var __webpack_modules__ = { groupBy: zod__rspack_import_2.euz('host').optional(), host: zod__rspack_import_2.YjP().min(1).max(256).optional(), limit: zod__rspack_import_2.aig().int().min(1).max(200).default(50), + cursor: zod__rspack_import_2.YjP().min(1).max(4096).optional(), modelProvider: zod__rspack_import_2.YjP().min(1).max(256).optional(), project: zod__rspack_import_2.YjP().min(1).max(256).optional(), port: zod__rspack_import_2.aig().int().min(1).max(65535).optional(), @@ -9702,64 +9712,173 @@ var __webpack_modules__ = { var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _remote_threads_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _payload_budget_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + const LIST_PAGE_PREFIX = 'desktop-list-v1:'; + const SEARCH_PAGE_PREFIX = 'desktop-search-v1:'; + const READ_PAGE_PREFIX = 'desktop-read-v1:'; async function appServerListThreads({ limit = 50, cursor, modelProviders = [] } = {}) { + let sourceCursor = cursor; + let skip = 0; + let fetchLimit = Math.min(limit, 25); + if (cursor?.startsWith(LIST_PAGE_PREFIX)) { + const state = (0, _payload_budget_js__rspack_import_4.i3)(LIST_PAGE_PREFIX, cursor); + if (!Number.isSafeInteger(state.skip) || state.skip < 1 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || state.cursor !== null && typeof state.cursor !== 'string') { + throw new Error('Invalid ChatGPT Desktop list page cursor'); + } + sourceCursor = state.cursor ?? undefined; + skip = state.skip; + fetchLimit = state.fetchLimit; + } const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit, - cursor, + limit: fetchLimit, + cursor: sourceCursor, modelProviders }); - return { + if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); + const base = { backend: 'app-server', - limit: out.limit, - nextCursor: out.nextCursor ?? null, - threads: out.threads.map(mapListedThread), + limit, modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; + const threads = []; + let consumed = skip; + for (const raw of out.threads.slice(skip)){ + if (threads.length >= limit) break; + let row = (0, _payload_budget_js__rspack_import_4.eX)(mapListedThread(raw)); + const probe = { + ...base, + threads: [ + ...threads, + row + ], + nextCursor: LIST_PAGE_PREFIX, + exitCode: 0 + }; + if ((0, _payload_budget_js__rspack_import_4.sQ)(probe) > 614400) { + if (threads.length) break; + row = (0, _payload_budget_js__rspack_import_4.MH)(row); + if ((0, _payload_budget_js__rspack_import_4.sQ)({ + ...base, + threads: [ + row + ], + nextCursor: LIST_PAGE_PREFIX, + exitCode: 0 + }) > 614400) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + threads.push(row); + consumed++; + } + const nextCursor = consumed < out.threads.length ? (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { + cursor: sourceCursor ?? null, + skip: consumed, + fetchLimit + }) : out.nextCursor ?? null; + return { + ...base, + threads, + nextCursor, + ...consumed < out.threads.length ? { + warnings: [ + 'List page stopped at the MCP byte budget; continue with nextCursor' + ] + } : {} + }; } - async function appServerSearchThreads({ query, limit = 50, modelProviders = [], project }) { + async function appServerSearchThreads({ query, limit = 50, cursor, modelProviders = [], project }) { const needle = query.trim().toLowerCase(); if (!needle) { return appServerListThreads({ limit, + cursor, modelProviders }); } const matched = []; - let cursor; - let exhausted = false; - for(let page = 0; page < 400 && matched.length < limit; page++){ + let sourceCursor; + let skip = 0; + if (cursor) { + const state = (0, _payload_budget_js__rspack_import_4.i3)(SEARCH_PAGE_PREFIX, cursor); + if (state.query !== query || state.project !== project || JSON.stringify(state.modelProviders) !== JSON.stringify(modelProviders) || !Number.isSafeInteger(state.skip) || state.skip < 0) { + throw new Error('Search cursor does not match this query and its filters'); + } + sourceCursor = state.cursor ?? undefined; + skip = state.skip; + } + const pageCursor = (rpcCursor, offset)=>(0, _payload_budget_js__rspack_import_4.oI)(SEARCH_PAGE_PREFIX, { + cursor: rpcCursor ?? null, + skip: offset, + query, + project, + modelProviders + }); + const base = { + backend: 'app-server', + limit, + query, + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined + }; + for(let page = 0; page < 400; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit: 25, - cursor, + cursor: sourceCursor, modelProviders }); - for (const thread of out.threads){ - const mapped = mapListedThread(thread); - if (threadMatchesQuery(mapped, needle) && (!project || [ + if (skip > out.threads.length) throw new Error('ChatGPT Desktop search cursor is stale'); + for(let index = skip; index < out.threads.length; index++){ + const mapped = mapListedThread(out.threads[index]); + if (!threadMatchesQuery(mapped, needle) || project && ![ mapped.project, mapped.projectId - ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase())))) matched.push(mapped); - if (matched.length >= limit) break; - } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') { - exhausted = true; - break; + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase()))) continue; + let row = (0, _payload_budget_js__rspack_import_4.eX)(mapped); + if ((0, _payload_budget_js__rspack_import_4.sQ)({ + ...base, + threads: [ + ...matched, + row + ], + nextCursor: SEARCH_PAGE_PREFIX, + exitCode: 0 + }) > 614400) { + if (matched.length) return { + ...base, + threads: matched, + nextCursor: pageCursor(sourceCursor, index), + warnings: [ + 'Search page stopped at the MCP byte budget; continue with nextCursor' + ] + }; + row = (0, _payload_budget_js__rspack_import_4.MH)(row); + } + matched.push(row); + if (matched.length >= limit) { + const nextCursor = index + 1 < out.threads.length ? pageCursor(sourceCursor, index + 1) : out.nextCursor ? pageCursor(out.nextCursor, 0) : null; + return { + ...base, + threads: matched, + nextCursor + }; + } } - cursor = out.nextCursor; + if (out.nextCursor == null) return { + ...base, + threads: matched, + nextCursor: null + }; + sourceCursor = out.nextCursor; + skip = 0; } return { - backend: 'app-server', - limit, - query, - nextCursor: null, - threads: matched.slice(0, limit), - modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, - ...!exhausted && matched.length < limit ? { - warnings: [ - 'Search stopped after 400 app-server pages; results may be incomplete' - ] - } : {} + ...base, + threads: matched, + nextCursor: pageCursor(sourceCursor, 0), + warnings: [ + 'Search stopped after 400 app-server pages; continue with nextCursor' + ] }; } async function discoverModelProviders() { @@ -9794,7 +9913,7 @@ var __webpack_modules__ = { complete }; } - async function appServerReadThread({ threadId, limit, full = false }) { + async function appServerReadThread({ threadId, limit, full = false, cursor }) { limit ??= full ? 2000 : 100; const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); @@ -9802,7 +9921,8 @@ var __webpack_modules__ = { try { return await readLocalThread(bare, { limit, - full + full, + cursor }); } catch (error) { if (isThreadNotLoaded(error) || isUnknownThread(error)) { @@ -9814,7 +9934,8 @@ var __webpack_modules__ = { try { return await readLocalThread(bare, { limit, - full + full, + cursor }); } catch (error) { throw maybeRemoteThreadError(error, bare); @@ -9834,13 +9955,15 @@ var __webpack_modules__ = { client.close(); } } - async function readLocalThread(bare, { limit, full }) { + async function readLocalThread(bare, { limit, full, cursor }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { const meta = await readThreadMetadata(client, bare); - const { turns, complete } = await listTurnsFull(client, bare, { + const { turns, complete, nextCursor } = await listTurnsFull(client, bare, { limit, - full + full, + cursor, + title: meta.title }); return { threadId: (0, _thread_ids_js__rspack_import_3.BS)(bare), @@ -9849,7 +9972,13 @@ var __webpack_modules__ = { limit, full, complete, - title: meta.title, + nextCursor, + ...complete ? {} : { + warnings: [ + 'Read page stopped before the end of the thread; continue with nextCursor to retrieve every turn and text fragment' + ] + }, + ...meta.title ? (0, _payload_budget_js__rspack_import_4.aA)(meta.title) : {}, cwd: meta.cwd, status: meta.status, modelProvider: meta.modelProvider, @@ -9931,56 +10060,200 @@ var __webpack_modules__ = { throw maybeRemoteThreadError(error, threadId); } } - async function listTurnsFull(client, threadId, { limit, full }) { - const collected = []; - let cursor; + async function listTurnsFull(client, threadId, { limit, full, cursor, title }) { + const state = cursor ? (0, _payload_budget_js__rspack_import_4.i3)(READ_PAGE_PREFIX, cursor) : null; + if (state && (state.threadId !== threadId || state.full !== full || !Number.isSafeInteger(state.skip) || state.skip < 0 || state.rpcCursor !== null && typeof state.rpcCursor !== 'string' || state.field !== undefined && ![ + 'text', + 'userText', + 'assistantText' + ].includes(state.field) || state.offset !== undefined && (!Number.isSafeInteger(state.offset) || state.offset < 0))) { + throw new Error('Read cursor does not match this thread or mode'); + } + let rpcCursor = state?.rpcCursor ?? undefined; + let skip = state?.skip ?? 0; + let fragmentField = state?.field; + let fragmentOffset = state?.offset ?? 0; let itemsView = true; let method = 'thread/turns/list'; const seen = new Set(); - let complete = false; - while(collected.length < limit){ + const turns = []; + const pageCursor = (source, index, field, offset)=>(0, _payload_budget_js__rspack_import_4.oI)(READ_PAGE_PREFIX, { + threadId, + full, + rpcCursor: source ?? null, + skip: index, + ...field ? { + field, + offset + } : {} + }); + const fits = (candidate)=>(0, _payload_budget_js__rspack_import_4.sQ)({ + threadId, + turns: [ + ...turns, + candidate + ], + backend: 'app-server', + limit, + full, + complete: false, + nextCursor: READ_PAGE_PREFIX, + title: title ? (0, _payload_budget_js__rspack_import_4.aA)(title).title : undefined, + warnings: [ + 'Read page stopped before the end of the thread; continue with nextCursor to retrieve every turn and text fragment' + ], + exitCode: 0 + }) <= 614400; + while(turns.length < limit){ let result; try { result = await client.request(method, { threadId, - limit: Math.min(10, limit - collected.length), + limit: Math.min(10, Math.max(limit - turns.length, skip + 1)), sortDirection: full ? 'asc' : 'desc', ...method === 'thread/turns/list' && itemsView ? { itemsView: 'full' } : {}, - ...cursor !== undefined ? { - cursor + ...rpcCursor !== undefined ? { + cursor: rpcCursor } : {} }); } catch (error) { const code = error?.rpc?.code; - if (collected.length === 0 && code === -32602 && itemsView) { + if (turns.length === 0 && code === -32602 && itemsView) { itemsView = false; continue; } - if (collected.length === 0 && code === -32601 && method === 'thread/turns/list') { + if (turns.length === 0 && code === -32601 && method === 'thread/turns/list') { method = 'thread/items/list'; continue; } throw maybeRemoteThreadError(error, threadId); } if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); - collected.push(...result.data); - if (result.nextCursor == null) { - complete = true; - break; + if (skip > result.data.length) throw new Error('Read cursor is stale'); + const pageTurns = normalizeTurns(result.data); + for(let index = skip; index < pageTurns.length; index++){ + const turn = pageTurns[index]; + if (!fragmentField && turns.length && !fits(turn)) { + return { + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, index) + }; + } + if (!fragmentField && fits(turn)) { + turns.push(turn); + } else { + const fields = [ + 'text', + 'userText', + 'assistantText' + ].filter((field)=>typeof turn[field] === 'string' && turn[field].length > 0); + let fieldIndex = fragmentField ? fields.indexOf(fragmentField) : 0; + if (fieldIndex < 0) throw new Error('Read fragment cursor is stale'); + for(; fieldIndex < fields.length; fieldIndex++){ + const field = fields[fieldIndex]; + const value = turn[field]; + let offset = field === fragmentField ? fragmentOffset : 0; + if (offset > value.length) throw new Error('Read fragment cursor is stale'); + while(offset < value.length){ + let size = Math.min(value.length - offset, 32768); + let fragment; + do { + let end = offset + size; + if (end < value.length && /[\uD800-\uDBFF]/u.test(value[end - 1])) end--; + const chunk = value.slice(offset, end); + fragment = { + turnKey: turn.turnKey, + role: turn.role, + text: field === 'text' ? chunk : '', + ...field === 'userText' ? { + userText: chunk + } : {}, + ...field === 'assistantText' ? { + assistantText: chunk + } : {}, + startedAt: turn.startedAt, + endedAt: turn.endedAt, + textTruncated: true, + continuation: { + field, + offsetChars: offset, + totalChars: value.length, + fieldComplete: end === value.length, + turnComplete: end === value.length && fieldIndex === fields.length - 1 + } + }; + if (fits(fragment)) { + size = end - offset; + break; + } + size = Math.floor(size / 2); + }while (size > 0); + if (size === 0) { + if (turns.length) return { + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, index, field, offset) + }; + throw new Error('Read fragment metadata exceeds the MCP result byte budget'); + } + turns.push(fragment); + offset += size; + if (turns.length >= limit || offset < value.length && !fits({ + ...fragment, + text: 'x'.repeat(32768) + })) { + return { + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, index, field, offset) + }; + } + } + } + fragmentField = undefined; + fragmentOffset = 0; + } + if (turns.length >= limit) { + const nextCursor = index + 1 < pageTurns.length ? pageCursor(rpcCursor, index + 1) : result.nextCursor ? pageCursor(result.nextCursor, 0) : null; + return { + turns: chronologicalPage(turns, full), + complete: nextCursor === null, + nextCursor + }; + } } + if (result.nextCursor == null) return { + turns: chronologicalPage(turns, full), + complete: true, + nextCursor: null + }; if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { throw new Error(`${method} returned an invalid or repeated cursor`); } seen.add(result.nextCursor); - cursor = result.nextCursor; + rpcCursor = result.nextCursor; + skip = 0; } - const turns = normalizeTurns(collected.slice(0, limit)); return { - turns: full ? turns : turns.reverse(), - complete - }; + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, skip) + }; + } + function chronologicalPage(turns, full) { + if (full) return turns; + const groups = []; + for (const turn of turns){ + const last = groups.at(-1); + if (last?.[0]?.turnKey === turn.turnKey) last.push(turn); + else groups.push([ + turn + ]); + } + return groups.reverse().flat(); } function normalizeTurns(raw) { const turns = []; @@ -11280,6 +11553,7 @@ var __webpack_modules__ = { var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); var _remote_threads_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _payload_budget_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); var _thread_ids_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, @@ -11359,7 +11633,28 @@ var __webpack_modules__ = { }); const offset = remoteOffset ?? 0; if (remoteOffset !== null || remoteInventory.threads.length >= limit) { - const page = remoteInventory.threads.slice(offset, offset + limit); + const page = []; + for (const thread of remoteInventory.threads.slice(offset, offset + limit)){ + const row = (0, _payload_budget_js__rspack_import_6.eX)(thread); + if ((0, _payload_budget_js__rspack_import_6.sQ)({ + ...remoteInventory, + threads: [ + ...page, + row + ], + nextCursor: REMOTE_PAGE_CURSOR, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost([ + ...page, + row + ]) + } : {} + }) > 614400) { + if (!page.length) throw new Error('ChatGPT Desktop remote thread row exceeds the MCP result byte budget'); + break; + } + page.push(row); + } const nextOffset = offset + page.length; const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; return { @@ -11471,16 +11766,16 @@ var __webpack_modules__ = { } const hostsSource = 'local+remote-thread-summaries-v3+managed-connections' + (cdpRows.length ? '+cdp' : ''); const remoteCounts = new Map(); - for (const thread of remotes){ - remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); - } - const remoteIds = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); - for (const thread of cdpRows){ - if (thread.location !== 'remote' || !thread.hostId) continue; - const id = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; - if (remoteIds.has(id)) continue; - remoteIds.add(id); - remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + const remoteInventory = finalizeThreadList({ + backend: cdpRows.length ? 'cdp' : 'remote-state', + limit: 10000, + threads: cdpRows.filter((thread)=>thread.location === 'remote') + }, { + limit: 10000, + remotes + }); + for (const thread of remoteInventory.threads){ + if (thread.hostId) remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); } const withCounts = [ ...byId.values() @@ -11521,10 +11816,21 @@ var __webpack_modules__ = { ]) ].sort(); return { - hosts: withCounts.map((host)=>host.hostId === 'local' ? { + hosts: withCounts.map((host)=>{ + const counted = host.hostId === 'local' ? { ...host, threadCount: localThreadCount - } : host), + } : host; + if (!counted.hostName) return counted; + const name = (0, _payload_budget_js__rspack_import_6.aA)(counted.hostName); + return { + ...counted, + hostName: name.title, + ...name.titleTruncated ? { + hostNameTruncated: true + } : {} + }; + }), hostsSource, modelProviders, modelProvidersSource, @@ -11542,25 +11848,27 @@ var __webpack_modules__ = { const appList = await this.#fallbacks.searchThreads({ query: options.query, limit, + cursor: options.cursor, modelProviders, project: options.project }); - const cdpList = await this.#tryCdpList({ + const cdpList = options.cursor ? null : await this.#tryCdpList({ limit }); const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const appMatches = new Set(appList.threads.map((thread)=>thread.threadId)); const withRemotes = finalizeThreadList(base, { limit: 10000, host, modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - remotes: this.#listRemotes() + remotes: options.cursor ? [] : this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); const filtered = { ...withRemotes, query: options.query, - threads: withRemotes.threads.filter((thread)=>threadMatchesQuery(thread, needle)) + threads: withRemotes.threads.filter((thread)=>appMatches.has(thread.threadId) || threadMatchesQuery(thread, needle)) }; const result = finalizeThreadList(filtered, { limit, @@ -11572,6 +11880,7 @@ var __webpack_modules__ = { }); return result; } catch (appError) { + if (options.cursor) throw appError; const cdpList = await this.#tryCdpList({ limit }); @@ -11606,6 +11915,7 @@ var __webpack_modules__ = { const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { + if (options.cursor) throw new Error('Temporary Desktop threads do not support read cursors'); await this.#ensureCdp(); return this.#cdp.readThread({ ...options, @@ -11617,10 +11927,12 @@ var __webpack_modules__ = { return await this.#fallbacks.readThread({ threadId: options.threadId, limit, - full + full, + cursor: options.cursor }); } catch (appError) { if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; + if (options.cursor) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; const fallback = await this.#cdp.readThread({ @@ -11812,7 +12124,7 @@ var __webpack_modules__ = { if (!projectMatches(thread, project)) return false; return true; }); - const limited = filtered.slice(0, limit); + const limited = filtered.slice(0, limit).map(_payload_budget_js__rspack_import_6.eX); const result = { backend: remotes.length ? base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' : base.backend === 'app-server' ? 'app-server+remote-state' : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend : base.backend, limit, @@ -11988,6 +12300,100 @@ var __webpack_modules__ = { jv: ()=>forceLoopbackWebSocketUrl }); }, + "./src/core/chatgpt-desktop/payload-budget.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + const DESKTOP_RESULT_BUDGET_BYTES = 600 * 1024; + const DESKTOP_THREAD_TITLE_CHARS = 200; + function serializedBytes(value) { + return Buffer.byteLength(JSON.stringify(value), 'utf8'); + } + function compact(value, maxChars) { + const normalized = value.replace(/\s+/gu, ' ').trim(); + const chars = Array.from(normalized); + return { + value: chars.slice(0, maxChars).join(''), + clipped: chars.length > maxChars + }; + } + function compactThreadRow(thread) { + const title = compact(thread.title, DESKTOP_THREAD_TITLE_CHARS); + const preview = typeof thread.preview === 'string' ? compact(thread.preview, 200) : null; + const cwd = typeof thread.cwd === 'string' ? compact(thread.cwd, 2048) : null; + const project = typeof thread.project === 'string' ? compact(thread.project, 256) : null; + const hostName = typeof thread.hostName === 'string' ? compact(thread.hostName, 256) : null; + return { + ...thread, + title: title.value, + ...title.clipped ? { + titleTruncated: true + } : {}, + ...preview ? { + preview: preview.value, + ...preview.clipped ? { + previewTruncated: true + } : {} + } : {}, + ...cwd ? { + cwd: cwd.value, + ...cwd.clipped ? { + cwdTruncated: true + } : {} + } : {}, + ...project ? { + project: project.value, + ...project.clipped ? { + projectTruncated: true + } : {} + } : {}, + ...hostName ? { + hostName: hostName.value, + ...hostName.clipped ? { + hostNameTruncated: true + } : {} + } : {} + }; + } + function compactThreadTitle(title) { + const out = compact(title, DESKTOP_THREAD_TITLE_CHARS); + return { + title: out.value, + titleTruncated: out.clipped + }; + } + function minimalThreadRow(thread) { + return { + threadId: thread.threadId, + title: compact(thread.title, DESKTOP_THREAD_TITLE_CHARS).value, + titleTruncated: true, + pinned: thread.pinned, + selected: thread.selected, + kind: thread.kind, + location: thread.location, + hostId: thread.hostId, + hostName: thread.hostName, + modelProvider: thread.modelProvider, + metadataTruncated: true + }; + } + function encodePageCursor(prefix, value) { + return prefix + Buffer.from(JSON.stringify(value)).toString('base64url'); + } + function decodePageCursor(prefix, cursor) { + if (!cursor.startsWith(prefix)) throw new Error('Invalid ChatGPT Desktop page cursor'); + try { + return JSON.parse(Buffer.from(cursor.slice(prefix.length), 'base64url').toString('utf8')); + } catch { + throw new Error('Invalid ChatGPT Desktop page cursor'); + } + } + __webpack_require__.d(__webpack_exports__, { + MH: ()=>minimalThreadRow, + aA: ()=>compactThreadTitle, + eX: ()=>compactThreadRow, + i3: ()=>decodePageCursor, + oI: ()=>encodePageCursor, + sQ: ()=>serializedBytes + }); + }, "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); @@ -12425,6 +12831,7 @@ var __webpack_modules__ = { port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), query: zod__rspack_import_4.YjP().min(1).max(512), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), project: zod__rspack_import_4.YjP().min(1).max(256).optional(), @@ -12438,6 +12845,7 @@ var __webpack_modules__ = { threadId, limit: zod__rspack_import_4.aig().int().min(1).max(2000).optional(), full: zod__rspack_import_4.zMY().default(false), + cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); const openThreadSchema = zod__rspack_import_4.Ikc({ @@ -12567,6 +12975,7 @@ var __webpack_modules__ = { return adapter.searchThreads({ query: input.query, limit: input.limit, + cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, project: input.project, @@ -12603,6 +13012,7 @@ var __webpack_modules__ = { threadId: input.threadId, limit: input.limit ?? (input.full ? 2000 : 100), full: input.full, + cursor: input.cursor, openTimeoutMs: input.openTimeoutMs })); return asResult({ @@ -41023,6 +41433,14 @@ var __webpack_modules__ = { "description": "Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.", "exitCode": "result", "options": [ + { + "description": "Opaque nextCursor from the prior read page", + "key": "cursor", + "kind": "string", + "option": "cursor", + "repeated": false, + "required": false + }, { "defaultValue": false, "key": "full", @@ -41078,6 +41496,14 @@ var __webpack_modules__ = { "description": "Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.", "exitCode": "result", "options": [ + { + "description": "Opaque nextCursor from a prior search page", + "key": "cursor", + "kind": "string", + "option": "cursor", + "repeated": false, + "required": false + }, { "choices": [ "host" diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index f84adbf..a023693 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8088,64 +8088,173 @@ var __webpack_modules__ = { var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _remote_threads_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _payload_budget_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + const LIST_PAGE_PREFIX = 'desktop-list-v1:'; + const SEARCH_PAGE_PREFIX = 'desktop-search-v1:'; + const READ_PAGE_PREFIX = 'desktop-read-v1:'; async function appServerListThreads({ limit = 50, cursor, modelProviders = [] } = {}) { + let sourceCursor = cursor; + let skip = 0; + let fetchLimit = Math.min(limit, 25); + if (cursor?.startsWith(LIST_PAGE_PREFIX)) { + const state = (0, _payload_budget_js__rspack_import_4.i3)(LIST_PAGE_PREFIX, cursor); + if (!Number.isSafeInteger(state.skip) || state.skip < 1 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || state.cursor !== null && typeof state.cursor !== 'string') { + throw new Error('Invalid ChatGPT Desktop list page cursor'); + } + sourceCursor = state.cursor ?? undefined; + skip = state.skip; + fetchLimit = state.fetchLimit; + } const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit, - cursor, + limit: fetchLimit, + cursor: sourceCursor, modelProviders }); - return { + if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); + const base = { backend: 'app-server', - limit: out.limit, - nextCursor: out.nextCursor ?? null, - threads: out.threads.map(mapListedThread), + limit, modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; + const threads = []; + let consumed = skip; + for (const raw of out.threads.slice(skip)){ + if (threads.length >= limit) break; + let row = (0, _payload_budget_js__rspack_import_4.eX)(mapListedThread(raw)); + const probe = { + ...base, + threads: [ + ...threads, + row + ], + nextCursor: LIST_PAGE_PREFIX, + exitCode: 0 + }; + if ((0, _payload_budget_js__rspack_import_4.sQ)(probe) > 614400) { + if (threads.length) break; + row = (0, _payload_budget_js__rspack_import_4.MH)(row); + if ((0, _payload_budget_js__rspack_import_4.sQ)({ + ...base, + threads: [ + row + ], + nextCursor: LIST_PAGE_PREFIX, + exitCode: 0 + }) > 614400) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + threads.push(row); + consumed++; + } + const nextCursor = consumed < out.threads.length ? (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { + cursor: sourceCursor ?? null, + skip: consumed, + fetchLimit + }) : out.nextCursor ?? null; + return { + ...base, + threads, + nextCursor, + ...consumed < out.threads.length ? { + warnings: [ + 'List page stopped at the MCP byte budget; continue with nextCursor' + ] + } : {} + }; } - async function appServerSearchThreads({ query, limit = 50, modelProviders = [], project }) { + async function appServerSearchThreads({ query, limit = 50, cursor, modelProviders = [], project }) { const needle = query.trim().toLowerCase(); if (!needle) { return appServerListThreads({ limit, + cursor, modelProviders }); } const matched = []; - let cursor; - let exhausted = false; - for(let page = 0; page < 400 && matched.length < limit; page++){ + let sourceCursor; + let skip = 0; + if (cursor) { + const state = (0, _payload_budget_js__rspack_import_4.i3)(SEARCH_PAGE_PREFIX, cursor); + if (state.query !== query || state.project !== project || JSON.stringify(state.modelProviders) !== JSON.stringify(modelProviders) || !Number.isSafeInteger(state.skip) || state.skip < 0) { + throw new Error('Search cursor does not match this query and its filters'); + } + sourceCursor = state.cursor ?? undefined; + skip = state.skip; + } + const pageCursor = (rpcCursor, offset)=>(0, _payload_budget_js__rspack_import_4.oI)(SEARCH_PAGE_PREFIX, { + cursor: rpcCursor ?? null, + skip: offset, + query, + project, + modelProviders + }); + const base = { + backend: 'app-server', + limit, + query, + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined + }; + for(let page = 0; page < 400; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit: 25, - cursor, + cursor: sourceCursor, modelProviders }); - for (const thread of out.threads){ - const mapped = mapListedThread(thread); - if (threadMatchesQuery(mapped, needle) && (!project || [ + if (skip > out.threads.length) throw new Error('ChatGPT Desktop search cursor is stale'); + for(let index = skip; index < out.threads.length; index++){ + const mapped = mapListedThread(out.threads[index]); + if (!threadMatchesQuery(mapped, needle) || project && ![ mapped.project, mapped.projectId - ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase())))) matched.push(mapped); - if (matched.length >= limit) break; - } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') { - exhausted = true; - break; + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase()))) continue; + let row = (0, _payload_budget_js__rspack_import_4.eX)(mapped); + if ((0, _payload_budget_js__rspack_import_4.sQ)({ + ...base, + threads: [ + ...matched, + row + ], + nextCursor: SEARCH_PAGE_PREFIX, + exitCode: 0 + }) > 614400) { + if (matched.length) return { + ...base, + threads: matched, + nextCursor: pageCursor(sourceCursor, index), + warnings: [ + 'Search page stopped at the MCP byte budget; continue with nextCursor' + ] + }; + row = (0, _payload_budget_js__rspack_import_4.MH)(row); + } + matched.push(row); + if (matched.length >= limit) { + const nextCursor = index + 1 < out.threads.length ? pageCursor(sourceCursor, index + 1) : out.nextCursor ? pageCursor(out.nextCursor, 0) : null; + return { + ...base, + threads: matched, + nextCursor + }; + } } - cursor = out.nextCursor; + if (out.nextCursor == null) return { + ...base, + threads: matched, + nextCursor: null + }; + sourceCursor = out.nextCursor; + skip = 0; } return { - backend: 'app-server', - limit, - query, - nextCursor: null, - threads: matched.slice(0, limit), - modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, - ...!exhausted && matched.length < limit ? { - warnings: [ - 'Search stopped after 400 app-server pages; results may be incomplete' - ] - } : {} + ...base, + threads: matched, + nextCursor: pageCursor(sourceCursor, 0), + warnings: [ + 'Search stopped after 400 app-server pages; continue with nextCursor' + ] }; } async function discoverModelProviders() { @@ -8180,7 +8289,7 @@ var __webpack_modules__ = { complete }; } - async function appServerReadThread({ threadId, limit, full = false }) { + async function appServerReadThread({ threadId, limit, full = false, cursor }) { limit ??= full ? 2000 : 100; const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); @@ -8188,7 +8297,8 @@ var __webpack_modules__ = { try { return await readLocalThread(bare, { limit, - full + full, + cursor }); } catch (error) { if (isThreadNotLoaded(error) || isUnknownThread(error)) { @@ -8200,7 +8310,8 @@ var __webpack_modules__ = { try { return await readLocalThread(bare, { limit, - full + full, + cursor }); } catch (error) { throw maybeRemoteThreadError(error, bare); @@ -8220,13 +8331,15 @@ var __webpack_modules__ = { client.close(); } } - async function readLocalThread(bare, { limit, full }) { + async function readLocalThread(bare, { limit, full, cursor }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { const meta = await readThreadMetadata(client, bare); - const { turns, complete } = await listTurnsFull(client, bare, { + const { turns, complete, nextCursor } = await listTurnsFull(client, bare, { limit, - full + full, + cursor, + title: meta.title }); return { threadId: (0, _thread_ids_js__rspack_import_3.BS)(bare), @@ -8235,7 +8348,13 @@ var __webpack_modules__ = { limit, full, complete, - title: meta.title, + nextCursor, + ...complete ? {} : { + warnings: [ + 'Read page stopped before the end of the thread; continue with nextCursor to retrieve every turn and text fragment' + ] + }, + ...meta.title ? (0, _payload_budget_js__rspack_import_4.aA)(meta.title) : {}, cwd: meta.cwd, status: meta.status, modelProvider: meta.modelProvider, @@ -8317,56 +8436,200 @@ var __webpack_modules__ = { throw maybeRemoteThreadError(error, threadId); } } - async function listTurnsFull(client, threadId, { limit, full }) { - const collected = []; - let cursor; + async function listTurnsFull(client, threadId, { limit, full, cursor, title }) { + const state = cursor ? (0, _payload_budget_js__rspack_import_4.i3)(READ_PAGE_PREFIX, cursor) : null; + if (state && (state.threadId !== threadId || state.full !== full || !Number.isSafeInteger(state.skip) || state.skip < 0 || state.rpcCursor !== null && typeof state.rpcCursor !== 'string' || state.field !== undefined && ![ + 'text', + 'userText', + 'assistantText' + ].includes(state.field) || state.offset !== undefined && (!Number.isSafeInteger(state.offset) || state.offset < 0))) { + throw new Error('Read cursor does not match this thread or mode'); + } + let rpcCursor = state?.rpcCursor ?? undefined; + let skip = state?.skip ?? 0; + let fragmentField = state?.field; + let fragmentOffset = state?.offset ?? 0; let itemsView = true; let method = 'thread/turns/list'; const seen = new Set(); - let complete = false; - while(collected.length < limit){ + const turns = []; + const pageCursor = (source, index, field, offset)=>(0, _payload_budget_js__rspack_import_4.oI)(READ_PAGE_PREFIX, { + threadId, + full, + rpcCursor: source ?? null, + skip: index, + ...field ? { + field, + offset + } : {} + }); + const fits = (candidate)=>(0, _payload_budget_js__rspack_import_4.sQ)({ + threadId, + turns: [ + ...turns, + candidate + ], + backend: 'app-server', + limit, + full, + complete: false, + nextCursor: READ_PAGE_PREFIX, + title: title ? (0, _payload_budget_js__rspack_import_4.aA)(title).title : undefined, + warnings: [ + 'Read page stopped before the end of the thread; continue with nextCursor to retrieve every turn and text fragment' + ], + exitCode: 0 + }) <= 614400; + while(turns.length < limit){ let result; try { result = await client.request(method, { threadId, - limit: Math.min(10, limit - collected.length), + limit: Math.min(10, Math.max(limit - turns.length, skip + 1)), sortDirection: full ? 'asc' : 'desc', ...method === 'thread/turns/list' && itemsView ? { itemsView: 'full' } : {}, - ...cursor !== undefined ? { - cursor + ...rpcCursor !== undefined ? { + cursor: rpcCursor } : {} }); } catch (error) { const code = error?.rpc?.code; - if (collected.length === 0 && code === -32602 && itemsView) { + if (turns.length === 0 && code === -32602 && itemsView) { itemsView = false; continue; } - if (collected.length === 0 && code === -32601 && method === 'thread/turns/list') { + if (turns.length === 0 && code === -32601 && method === 'thread/turns/list') { method = 'thread/items/list'; continue; } throw maybeRemoteThreadError(error, threadId); } if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); - collected.push(...result.data); - if (result.nextCursor == null) { - complete = true; - break; + if (skip > result.data.length) throw new Error('Read cursor is stale'); + const pageTurns = normalizeTurns(result.data); + for(let index = skip; index < pageTurns.length; index++){ + const turn = pageTurns[index]; + if (!fragmentField && turns.length && !fits(turn)) { + return { + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, index) + }; + } + if (!fragmentField && fits(turn)) { + turns.push(turn); + } else { + const fields = [ + 'text', + 'userText', + 'assistantText' + ].filter((field)=>typeof turn[field] === 'string' && turn[field].length > 0); + let fieldIndex = fragmentField ? fields.indexOf(fragmentField) : 0; + if (fieldIndex < 0) throw new Error('Read fragment cursor is stale'); + for(; fieldIndex < fields.length; fieldIndex++){ + const field = fields[fieldIndex]; + const value = turn[field]; + let offset = field === fragmentField ? fragmentOffset : 0; + if (offset > value.length) throw new Error('Read fragment cursor is stale'); + while(offset < value.length){ + let size = Math.min(value.length - offset, 32768); + let fragment; + do { + let end = offset + size; + if (end < value.length && /[\uD800-\uDBFF]/u.test(value[end - 1])) end--; + const chunk = value.slice(offset, end); + fragment = { + turnKey: turn.turnKey, + role: turn.role, + text: field === 'text' ? chunk : '', + ...field === 'userText' ? { + userText: chunk + } : {}, + ...field === 'assistantText' ? { + assistantText: chunk + } : {}, + startedAt: turn.startedAt, + endedAt: turn.endedAt, + textTruncated: true, + continuation: { + field, + offsetChars: offset, + totalChars: value.length, + fieldComplete: end === value.length, + turnComplete: end === value.length && fieldIndex === fields.length - 1 + } + }; + if (fits(fragment)) { + size = end - offset; + break; + } + size = Math.floor(size / 2); + }while (size > 0); + if (size === 0) { + if (turns.length) return { + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, index, field, offset) + }; + throw new Error('Read fragment metadata exceeds the MCP result byte budget'); + } + turns.push(fragment); + offset += size; + if (turns.length >= limit || offset < value.length && !fits({ + ...fragment, + text: 'x'.repeat(32768) + })) { + return { + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, index, field, offset) + }; + } + } + } + fragmentField = undefined; + fragmentOffset = 0; + } + if (turns.length >= limit) { + const nextCursor = index + 1 < pageTurns.length ? pageCursor(rpcCursor, index + 1) : result.nextCursor ? pageCursor(result.nextCursor, 0) : null; + return { + turns: chronologicalPage(turns, full), + complete: nextCursor === null, + nextCursor + }; + } } + if (result.nextCursor == null) return { + turns: chronologicalPage(turns, full), + complete: true, + nextCursor: null + }; if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { throw new Error(`${method} returned an invalid or repeated cursor`); } seen.add(result.nextCursor); - cursor = result.nextCursor; + rpcCursor = result.nextCursor; + skip = 0; } - const turns = normalizeTurns(collected.slice(0, limit)); return { - turns: full ? turns : turns.reverse(), - complete - }; + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, skip) + }; + } + function chronologicalPage(turns, full) { + if (full) return turns; + const groups = []; + for (const turn of turns){ + const last = groups.at(-1); + if (last?.[0]?.turnKey === turn.turnKey) last.push(turn); + else groups.push([ + turn + ]); + } + return groups.reverse().flat(); } function normalizeTurns(raw) { const turns = []; @@ -9666,6 +9929,7 @@ var __webpack_modules__ = { var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); var _remote_threads_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _payload_budget_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); var _thread_ids_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, @@ -9745,7 +10009,28 @@ var __webpack_modules__ = { }); const offset = remoteOffset ?? 0; if (remoteOffset !== null || remoteInventory.threads.length >= limit) { - const page = remoteInventory.threads.slice(offset, offset + limit); + const page = []; + for (const thread of remoteInventory.threads.slice(offset, offset + limit)){ + const row = (0, _payload_budget_js__rspack_import_6.eX)(thread); + if ((0, _payload_budget_js__rspack_import_6.sQ)({ + ...remoteInventory, + threads: [ + ...page, + row + ], + nextCursor: REMOTE_PAGE_CURSOR, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost([ + ...page, + row + ]) + } : {} + }) > 614400) { + if (!page.length) throw new Error('ChatGPT Desktop remote thread row exceeds the MCP result byte budget'); + break; + } + page.push(row); + } const nextOffset = offset + page.length; const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; return { @@ -9857,16 +10142,16 @@ var __webpack_modules__ = { } const hostsSource = 'local+remote-thread-summaries-v3+managed-connections' + (cdpRows.length ? '+cdp' : ''); const remoteCounts = new Map(); - for (const thread of remotes){ - remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); - } - const remoteIds = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); - for (const thread of cdpRows){ - if (thread.location !== 'remote' || !thread.hostId) continue; - const id = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; - if (remoteIds.has(id)) continue; - remoteIds.add(id); - remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + const remoteInventory = finalizeThreadList({ + backend: cdpRows.length ? 'cdp' : 'remote-state', + limit: 10000, + threads: cdpRows.filter((thread)=>thread.location === 'remote') + }, { + limit: 10000, + remotes + }); + for (const thread of remoteInventory.threads){ + if (thread.hostId) remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); } const withCounts = [ ...byId.values() @@ -9907,10 +10192,21 @@ var __webpack_modules__ = { ]) ].sort(); return { - hosts: withCounts.map((host)=>host.hostId === 'local' ? { + hosts: withCounts.map((host)=>{ + const counted = host.hostId === 'local' ? { ...host, threadCount: localThreadCount - } : host), + } : host; + if (!counted.hostName) return counted; + const name = (0, _payload_budget_js__rspack_import_6.aA)(counted.hostName); + return { + ...counted, + hostName: name.title, + ...name.titleTruncated ? { + hostNameTruncated: true + } : {} + }; + }), hostsSource, modelProviders, modelProvidersSource, @@ -9928,25 +10224,27 @@ var __webpack_modules__ = { const appList = await this.#fallbacks.searchThreads({ query: options.query, limit, + cursor: options.cursor, modelProviders, project: options.project }); - const cdpList = await this.#tryCdpList({ + const cdpList = options.cursor ? null : await this.#tryCdpList({ limit }); const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const appMatches = new Set(appList.threads.map((thread)=>thread.threadId)); const withRemotes = finalizeThreadList(base, { limit: 10000, host, modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - remotes: this.#listRemotes() + remotes: options.cursor ? [] : this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); const filtered = { ...withRemotes, query: options.query, - threads: withRemotes.threads.filter((thread)=>threadMatchesQuery(thread, needle)) + threads: withRemotes.threads.filter((thread)=>appMatches.has(thread.threadId) || threadMatchesQuery(thread, needle)) }; const result = finalizeThreadList(filtered, { limit, @@ -9958,6 +10256,7 @@ var __webpack_modules__ = { }); return result; } catch (appError) { + if (options.cursor) throw appError; const cdpList = await this.#tryCdpList({ limit }); @@ -9992,6 +10291,7 @@ var __webpack_modules__ = { const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { + if (options.cursor) throw new Error('Temporary Desktop threads do not support read cursors'); await this.#ensureCdp(); return this.#cdp.readThread({ ...options, @@ -10003,10 +10303,12 @@ var __webpack_modules__ = { return await this.#fallbacks.readThread({ threadId: options.threadId, limit, - full + full, + cursor: options.cursor }); } catch (appError) { if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; + if (options.cursor) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; const fallback = await this.#cdp.readThread({ @@ -10198,7 +10500,7 @@ var __webpack_modules__ = { if (!projectMatches(thread, project)) return false; return true; }); - const limited = filtered.slice(0, limit); + const limited = filtered.slice(0, limit).map(_payload_budget_js__rspack_import_6.eX); const result = { backend: remotes.length ? base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' : base.backend === 'app-server' ? 'app-server+remote-state' : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend : base.backend, limit, @@ -10374,6 +10676,100 @@ var __webpack_modules__ = { jv: ()=>forceLoopbackWebSocketUrl }); }, + "./src/core/chatgpt-desktop/payload-budget.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + const DESKTOP_RESULT_BUDGET_BYTES = 600 * 1024; + const DESKTOP_THREAD_TITLE_CHARS = 200; + function serializedBytes(value) { + return Buffer.byteLength(JSON.stringify(value), 'utf8'); + } + function compact(value, maxChars) { + const normalized = value.replace(/\s+/gu, ' ').trim(); + const chars = Array.from(normalized); + return { + value: chars.slice(0, maxChars).join(''), + clipped: chars.length > maxChars + }; + } + function compactThreadRow(thread) { + const title = compact(thread.title, DESKTOP_THREAD_TITLE_CHARS); + const preview = typeof thread.preview === 'string' ? compact(thread.preview, 200) : null; + const cwd = typeof thread.cwd === 'string' ? compact(thread.cwd, 2048) : null; + const project = typeof thread.project === 'string' ? compact(thread.project, 256) : null; + const hostName = typeof thread.hostName === 'string' ? compact(thread.hostName, 256) : null; + return { + ...thread, + title: title.value, + ...title.clipped ? { + titleTruncated: true + } : {}, + ...preview ? { + preview: preview.value, + ...preview.clipped ? { + previewTruncated: true + } : {} + } : {}, + ...cwd ? { + cwd: cwd.value, + ...cwd.clipped ? { + cwdTruncated: true + } : {} + } : {}, + ...project ? { + project: project.value, + ...project.clipped ? { + projectTruncated: true + } : {} + } : {}, + ...hostName ? { + hostName: hostName.value, + ...hostName.clipped ? { + hostNameTruncated: true + } : {} + } : {} + }; + } + function compactThreadTitle(title) { + const out = compact(title, DESKTOP_THREAD_TITLE_CHARS); + return { + title: out.value, + titleTruncated: out.clipped + }; + } + function minimalThreadRow(thread) { + return { + threadId: thread.threadId, + title: compact(thread.title, DESKTOP_THREAD_TITLE_CHARS).value, + titleTruncated: true, + pinned: thread.pinned, + selected: thread.selected, + kind: thread.kind, + location: thread.location, + hostId: thread.hostId, + hostName: thread.hostName, + modelProvider: thread.modelProvider, + metadataTruncated: true + }; + } + function encodePageCursor(prefix, value) { + return prefix + Buffer.from(JSON.stringify(value)).toString('base64url'); + } + function decodePageCursor(prefix, cursor) { + if (!cursor.startsWith(prefix)) throw new Error('Invalid ChatGPT Desktop page cursor'); + try { + return JSON.parse(Buffer.from(cursor.slice(prefix.length), 'base64url').toString('utf8')); + } catch { + throw new Error('Invalid ChatGPT Desktop page cursor'); + } + } + __webpack_require__.d(__webpack_exports__, { + MH: ()=>minimalThreadRow, + aA: ()=>compactThreadTitle, + eX: ()=>compactThreadRow, + i3: ()=>decodePageCursor, + oI: ()=>encodePageCursor, + sQ: ()=>serializedBytes + }); + }, "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); @@ -10811,6 +11207,7 @@ var __webpack_modules__ = { port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), query: zod__rspack_import_4.YjP().min(1).max(512), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), project: zod__rspack_import_4.YjP().min(1).max(256).optional(), @@ -10824,6 +11221,7 @@ var __webpack_modules__ = { threadId, limit: zod__rspack_import_4.aig().int().min(1).max(2000).optional(), full: zod__rspack_import_4.zMY().default(false), + cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); const openThreadSchema = zod__rspack_import_4.Ikc({ @@ -10953,6 +11351,7 @@ var __webpack_modules__ = { return adapter.searchThreads({ query: input.query, limit: input.limit, + cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, project: input.project, @@ -10989,6 +11388,7 @@ var __webpack_modules__ = { threadId: input.threadId, limit: input.limit ?? (input.full ? 2000 : 100), full: input.full, + cursor: input.cursor, openTimeoutMs: input.openTimeoutMs })); return asResult({ @@ -11773,7 +12173,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List Desktop threads, then pass nextCursor as cursor until null. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', + description: 'List Desktop threads, then pass nextCursor as cursor until null. Pages may stop early at the MCP byte budget. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', annotations: { readOnlyHint: true }, @@ -11890,7 +12290,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Recent defaults to 100 turns; full pages up to 2000 from the start. Archived threads remain readable. complete:false means partial history; warnings preserve app-server/frame errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.', + description: 'Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Pass nextCursor back as cursor with the same threadId/full mode until complete:true. Pages stop at a byte budget; oversized turns use ordered continuation fragments with stable turnKey and field offsets, without dropping text. Archived threads remain readable. Warnings explain partial pages or app-server errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.', annotations: { readOnlyHint: true }, @@ -11913,6 +12313,10 @@ var __webpack_modules__ = { limit: { type: 'number' }, + cursor: { + type: 'string', + description: 'Opaque nextCursor from the prior read page. Keep threadId and full unchanged.' + }, full: { type: 'boolean', description: 'When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.' @@ -11949,7 +12353,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop search threads', - description: 'Search Desktop thread metadata by case-insensitive substring. Dynamic hostId/hostName, modelProvider, and project filters apply. Search scans bounded app-server pages and reports warnings if incomplete; use list_threads cursor for exhaustive paging. Remote results identify hostId and cannot be read on this Mac.', + description: 'Search full Desktop thread metadata by case-insensitive substring. Display titles are capped at 200 characters with titleTruncated:true. Pass nextCursor as cursor with unchanged query and filters to retrieve all matches. Dynamic hostId/hostName, modelProvider, and project filters apply. Remote results identify hostId and cannot be read on this Mac.', annotations: { readOnlyHint: true }, @@ -11971,6 +12375,10 @@ var __webpack_modules__ = { default: 50, description: 'Maximum matches.' }, + cursor: { + type: 'string', + description: 'Opaque nextCursor from the previous search page; keep query and filters unchanged.' + }, host: { type: 'string', description: 'Any string filter for machine/location. Reserved: "all" (default), "local". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.' @@ -28247,7 +28655,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "List Desktop threads, then pass nextCursor as cursor until null. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.", + "description": "List Desktop threads, then pass nextCursor as cursor until null. Pages may stop early at the MCP byte budget. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -28334,10 +28742,14 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Recent defaults to 100 turns; full pages up to 2000 from the start. Archived threads remain readable. complete:false means partial history; warnings preserve app-server/frame errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.", + "description": "Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Pass nextCursor back as cursor with the same threadId/full mode until complete:true. Pages stop at a byte budget; oversized turns use ordered continuation fragments with stable turnKey and field offsets, without dropping text. Archived threads remain readable. Warnings explain partial pages or app-server errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "cursor": { + "description": "Opaque nextCursor from the prior read page. Keep threadId and full unchanged.", + "type": "string" + }, "full": { "description": "When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.", "type": "boolean" @@ -28378,10 +28790,14 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "Search Desktop thread metadata by case-insensitive substring. Dynamic hostId/hostName, modelProvider, and project filters apply. Search scans bounded app-server pages and reports warnings if incomplete; use list_threads cursor for exhaustive paging. Remote results identify hostId and cannot be read on this Mac.", + "description": "Search full Desktop thread metadata by case-insensitive substring. Display titles are capped at 200 characters with titleTruncated:true. Pass nextCursor as cursor with unchanged query and filters to retrieve all matches. Dynamic hostId/hostName, modelProvider, and project filters apply. Remote results identify hostId and cannot be read on this Mac.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "cursor": { + "description": "Opaque nextCursor from the previous search page; keep query and filters unchanged.", + "type": "string" + }, "groupBy": { "description": "When \"host\", also return groups[] keyed by host (grouping mode, not a host id).", "enum": [ diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index 383c5b5..5e5fdb6 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -6496,64 +6496,173 @@ var __webpack_modules__ = { var _codex_bridge_js__rspack_import_0 = __webpack_require__("./src/core/codex-bridge.js"); var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _remote_threads_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _payload_budget_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + const LIST_PAGE_PREFIX = 'desktop-list-v1:'; + const SEARCH_PAGE_PREFIX = 'desktop-search-v1:'; + const READ_PAGE_PREFIX = 'desktop-read-v1:'; async function appServerListThreads({ limit = 50, cursor, modelProviders = [] } = {}) { + let sourceCursor = cursor; + let skip = 0; + let fetchLimit = Math.min(limit, 25); + if (cursor?.startsWith(LIST_PAGE_PREFIX)) { + const state = (0, _payload_budget_js__rspack_import_4.i3)(LIST_PAGE_PREFIX, cursor); + if (!Number.isSafeInteger(state.skip) || state.skip < 1 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || state.cursor !== null && typeof state.cursor !== 'string') { + throw new Error('Invalid ChatGPT Desktop list page cursor'); + } + sourceCursor = state.cursor ?? undefined; + skip = state.skip; + fetchLimit = state.fetchLimit; + } const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit, - cursor, + limit: fetchLimit, + cursor: sourceCursor, modelProviders }); - return { + if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); + const base = { backend: 'app-server', - limit: out.limit, - nextCursor: out.nextCursor ?? null, - threads: out.threads.map(mapListedThread), + limit, modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; + const threads = []; + let consumed = skip; + for (const raw of out.threads.slice(skip)){ + if (threads.length >= limit) break; + let row = (0, _payload_budget_js__rspack_import_4.eX)(mapListedThread(raw)); + const probe = { + ...base, + threads: [ + ...threads, + row + ], + nextCursor: LIST_PAGE_PREFIX, + exitCode: 0 + }; + if ((0, _payload_budget_js__rspack_import_4.sQ)(probe) > 614400) { + if (threads.length) break; + row = (0, _payload_budget_js__rspack_import_4.MH)(row); + if ((0, _payload_budget_js__rspack_import_4.sQ)({ + ...base, + threads: [ + row + ], + nextCursor: LIST_PAGE_PREFIX, + exitCode: 0 + }) > 614400) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + threads.push(row); + consumed++; + } + const nextCursor = consumed < out.threads.length ? (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { + cursor: sourceCursor ?? null, + skip: consumed, + fetchLimit + }) : out.nextCursor ?? null; + return { + ...base, + threads, + nextCursor, + ...consumed < out.threads.length ? { + warnings: [ + 'List page stopped at the MCP byte budget; continue with nextCursor' + ] + } : {} + }; } - async function appServerSearchThreads({ query, limit = 50, modelProviders = [], project }) { + async function appServerSearchThreads({ query, limit = 50, cursor, modelProviders = [], project }) { const needle = query.trim().toLowerCase(); if (!needle) { return appServerListThreads({ limit, + cursor, modelProviders }); } const matched = []; - let cursor; - let exhausted = false; - for(let page = 0; page < 400 && matched.length < limit; page++){ + let sourceCursor; + let skip = 0; + if (cursor) { + const state = (0, _payload_budget_js__rspack_import_4.i3)(SEARCH_PAGE_PREFIX, cursor); + if (state.query !== query || state.project !== project || JSON.stringify(state.modelProviders) !== JSON.stringify(modelProviders) || !Number.isSafeInteger(state.skip) || state.skip < 0) { + throw new Error('Search cursor does not match this query and its filters'); + } + sourceCursor = state.cursor ?? undefined; + skip = state.skip; + } + const pageCursor = (rpcCursor, offset)=>(0, _payload_budget_js__rspack_import_4.oI)(SEARCH_PAGE_PREFIX, { + cursor: rpcCursor ?? null, + skip: offset, + query, + project, + modelProviders + }); + const base = { + backend: 'app-server', + limit, + query, + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined + }; + for(let page = 0; page < 400; page++){ const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ limit: 25, - cursor, + cursor: sourceCursor, modelProviders }); - for (const thread of out.threads){ - const mapped = mapListedThread(thread); - if (threadMatchesQuery(mapped, needle) && (!project || [ + if (skip > out.threads.length) throw new Error('ChatGPT Desktop search cursor is stale'); + for(let index = skip; index < out.threads.length; index++){ + const mapped = mapListedThread(out.threads[index]); + if (!threadMatchesQuery(mapped, needle) || project && ![ mapped.project, mapped.projectId - ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase())))) matched.push(mapped); - if (matched.length >= limit) break; - } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') { - exhausted = true; - break; + ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase()))) continue; + let row = (0, _payload_budget_js__rspack_import_4.eX)(mapped); + if ((0, _payload_budget_js__rspack_import_4.sQ)({ + ...base, + threads: [ + ...matched, + row + ], + nextCursor: SEARCH_PAGE_PREFIX, + exitCode: 0 + }) > 614400) { + if (matched.length) return { + ...base, + threads: matched, + nextCursor: pageCursor(sourceCursor, index), + warnings: [ + 'Search page stopped at the MCP byte budget; continue with nextCursor' + ] + }; + row = (0, _payload_budget_js__rspack_import_4.MH)(row); + } + matched.push(row); + if (matched.length >= limit) { + const nextCursor = index + 1 < out.threads.length ? pageCursor(sourceCursor, index + 1) : out.nextCursor ? pageCursor(out.nextCursor, 0) : null; + return { + ...base, + threads: matched, + nextCursor + }; + } } - cursor = out.nextCursor; + if (out.nextCursor == null) return { + ...base, + threads: matched, + nextCursor: null + }; + sourceCursor = out.nextCursor; + skip = 0; } return { - backend: 'app-server', - limit, - query, - nextCursor: null, - threads: matched.slice(0, limit), - modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, - ...!exhausted && matched.length < limit ? { - warnings: [ - 'Search stopped after 400 app-server pages; results may be incomplete' - ] - } : {} + ...base, + threads: matched, + nextCursor: pageCursor(sourceCursor, 0), + warnings: [ + 'Search stopped after 400 app-server pages; continue with nextCursor' + ] }; } async function discoverModelProviders() { @@ -6588,7 +6697,7 @@ var __webpack_modules__ = { complete }; } - async function appServerReadThread({ threadId, limit, full = false }) { + async function appServerReadThread({ threadId, limit, full = false, cursor }) { limit ??= full ? 2000 : 100; const bare = (0, _thread_ids_js__rspack_import_3.NM)(threadId); const remote = (0, _remote_threads_js__rspack_import_2.KI)(bare); @@ -6596,7 +6705,8 @@ var __webpack_modules__ = { try { return await readLocalThread(bare, { limit, - full + full, + cursor }); } catch (error) { if (isThreadNotLoaded(error) || isUnknownThread(error)) { @@ -6608,7 +6718,8 @@ var __webpack_modules__ = { try { return await readLocalThread(bare, { limit, - full + full, + cursor }); } catch (error) { throw maybeRemoteThreadError(error, bare); @@ -6628,13 +6739,15 @@ var __webpack_modules__ = { client.close(); } } - async function readLocalThread(bare, { limit, full }) { + async function readLocalThread(bare, { limit, full, cursor }) { const { client } = await (0, _codex_bridge_js__rspack_import_0.eC)(); try { const meta = await readThreadMetadata(client, bare); - const { turns, complete } = await listTurnsFull(client, bare, { + const { turns, complete, nextCursor } = await listTurnsFull(client, bare, { limit, - full + full, + cursor, + title: meta.title }); return { threadId: (0, _thread_ids_js__rspack_import_3.BS)(bare), @@ -6643,7 +6756,13 @@ var __webpack_modules__ = { limit, full, complete, - title: meta.title, + nextCursor, + ...complete ? {} : { + warnings: [ + 'Read page stopped before the end of the thread; continue with nextCursor to retrieve every turn and text fragment' + ] + }, + ...meta.title ? (0, _payload_budget_js__rspack_import_4.aA)(meta.title) : {}, cwd: meta.cwd, status: meta.status, modelProvider: meta.modelProvider, @@ -6725,56 +6844,200 @@ var __webpack_modules__ = { throw maybeRemoteThreadError(error, threadId); } } - async function listTurnsFull(client, threadId, { limit, full }) { - const collected = []; - let cursor; + async function listTurnsFull(client, threadId, { limit, full, cursor, title }) { + const state = cursor ? (0, _payload_budget_js__rspack_import_4.i3)(READ_PAGE_PREFIX, cursor) : null; + if (state && (state.threadId !== threadId || state.full !== full || !Number.isSafeInteger(state.skip) || state.skip < 0 || state.rpcCursor !== null && typeof state.rpcCursor !== 'string' || state.field !== undefined && ![ + 'text', + 'userText', + 'assistantText' + ].includes(state.field) || state.offset !== undefined && (!Number.isSafeInteger(state.offset) || state.offset < 0))) { + throw new Error('Read cursor does not match this thread or mode'); + } + let rpcCursor = state?.rpcCursor ?? undefined; + let skip = state?.skip ?? 0; + let fragmentField = state?.field; + let fragmentOffset = state?.offset ?? 0; let itemsView = true; let method = 'thread/turns/list'; const seen = new Set(); - let complete = false; - while(collected.length < limit){ + const turns = []; + const pageCursor = (source, index, field, offset)=>(0, _payload_budget_js__rspack_import_4.oI)(READ_PAGE_PREFIX, { + threadId, + full, + rpcCursor: source ?? null, + skip: index, + ...field ? { + field, + offset + } : {} + }); + const fits = (candidate)=>(0, _payload_budget_js__rspack_import_4.sQ)({ + threadId, + turns: [ + ...turns, + candidate + ], + backend: 'app-server', + limit, + full, + complete: false, + nextCursor: READ_PAGE_PREFIX, + title: title ? (0, _payload_budget_js__rspack_import_4.aA)(title).title : undefined, + warnings: [ + 'Read page stopped before the end of the thread; continue with nextCursor to retrieve every turn and text fragment' + ], + exitCode: 0 + }) <= 614400; + while(turns.length < limit){ let result; try { result = await client.request(method, { threadId, - limit: Math.min(10, limit - collected.length), + limit: Math.min(10, Math.max(limit - turns.length, skip + 1)), sortDirection: full ? 'asc' : 'desc', ...method === 'thread/turns/list' && itemsView ? { itemsView: 'full' } : {}, - ...cursor !== undefined ? { - cursor + ...rpcCursor !== undefined ? { + cursor: rpcCursor } : {} }); } catch (error) { const code = error?.rpc?.code; - if (collected.length === 0 && code === -32602 && itemsView) { + if (turns.length === 0 && code === -32602 && itemsView) { itemsView = false; continue; } - if (collected.length === 0 && code === -32601 && method === 'thread/turns/list') { + if (turns.length === 0 && code === -32601 && method === 'thread/turns/list') { method = 'thread/items/list'; continue; } throw maybeRemoteThreadError(error, threadId); } if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); - collected.push(...result.data); - if (result.nextCursor == null) { - complete = true; - break; + if (skip > result.data.length) throw new Error('Read cursor is stale'); + const pageTurns = normalizeTurns(result.data); + for(let index = skip; index < pageTurns.length; index++){ + const turn = pageTurns[index]; + if (!fragmentField && turns.length && !fits(turn)) { + return { + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, index) + }; + } + if (!fragmentField && fits(turn)) { + turns.push(turn); + } else { + const fields = [ + 'text', + 'userText', + 'assistantText' + ].filter((field)=>typeof turn[field] === 'string' && turn[field].length > 0); + let fieldIndex = fragmentField ? fields.indexOf(fragmentField) : 0; + if (fieldIndex < 0) throw new Error('Read fragment cursor is stale'); + for(; fieldIndex < fields.length; fieldIndex++){ + const field = fields[fieldIndex]; + const value = turn[field]; + let offset = field === fragmentField ? fragmentOffset : 0; + if (offset > value.length) throw new Error('Read fragment cursor is stale'); + while(offset < value.length){ + let size = Math.min(value.length - offset, 32768); + let fragment; + do { + let end = offset + size; + if (end < value.length && /[\uD800-\uDBFF]/u.test(value[end - 1])) end--; + const chunk = value.slice(offset, end); + fragment = { + turnKey: turn.turnKey, + role: turn.role, + text: field === 'text' ? chunk : '', + ...field === 'userText' ? { + userText: chunk + } : {}, + ...field === 'assistantText' ? { + assistantText: chunk + } : {}, + startedAt: turn.startedAt, + endedAt: turn.endedAt, + textTruncated: true, + continuation: { + field, + offsetChars: offset, + totalChars: value.length, + fieldComplete: end === value.length, + turnComplete: end === value.length && fieldIndex === fields.length - 1 + } + }; + if (fits(fragment)) { + size = end - offset; + break; + } + size = Math.floor(size / 2); + }while (size > 0); + if (size === 0) { + if (turns.length) return { + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, index, field, offset) + }; + throw new Error('Read fragment metadata exceeds the MCP result byte budget'); + } + turns.push(fragment); + offset += size; + if (turns.length >= limit || offset < value.length && !fits({ + ...fragment, + text: 'x'.repeat(32768) + })) { + return { + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, index, field, offset) + }; + } + } + } + fragmentField = undefined; + fragmentOffset = 0; + } + if (turns.length >= limit) { + const nextCursor = index + 1 < pageTurns.length ? pageCursor(rpcCursor, index + 1) : result.nextCursor ? pageCursor(result.nextCursor, 0) : null; + return { + turns: chronologicalPage(turns, full), + complete: nextCursor === null, + nextCursor + }; + } } + if (result.nextCursor == null) return { + turns: chronologicalPage(turns, full), + complete: true, + nextCursor: null + }; if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { throw new Error(`${method} returned an invalid or repeated cursor`); } seen.add(result.nextCursor); - cursor = result.nextCursor; + rpcCursor = result.nextCursor; + skip = 0; } - const turns = normalizeTurns(collected.slice(0, limit)); return { - turns: full ? turns : turns.reverse(), - complete - }; + turns: chronologicalPage(turns, full), + complete: false, + nextCursor: pageCursor(rpcCursor, skip) + }; + } + function chronologicalPage(turns, full) { + if (full) return turns; + const groups = []; + for (const turn of turns){ + const last = groups.at(-1); + if (last?.[0]?.turnKey === turn.turnKey) last.push(turn); + else groups.push([ + turn + ]); + } + return groups.reverse().flat(); } function normalizeTurns(raw) { const turns = []; @@ -8074,6 +8337,7 @@ var __webpack_modules__ = { var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); var _remote_threads_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _payload_budget_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); var _thread_ids_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { listThreads: _app_server_fallback_js__rspack_import_1.OI, @@ -8153,7 +8417,28 @@ var __webpack_modules__ = { }); const offset = remoteOffset ?? 0; if (remoteOffset !== null || remoteInventory.threads.length >= limit) { - const page = remoteInventory.threads.slice(offset, offset + limit); + const page = []; + for (const thread of remoteInventory.threads.slice(offset, offset + limit)){ + const row = (0, _payload_budget_js__rspack_import_6.eX)(thread); + if ((0, _payload_budget_js__rspack_import_6.sQ)({ + ...remoteInventory, + threads: [ + ...page, + row + ], + nextCursor: REMOTE_PAGE_CURSOR, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost([ + ...page, + row + ]) + } : {} + }) > 614400) { + if (!page.length) throw new Error('ChatGPT Desktop remote thread row exceeds the MCP result byte budget'); + break; + } + page.push(row); + } const nextOffset = offset + page.length; const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; return { @@ -8265,16 +8550,16 @@ var __webpack_modules__ = { } const hostsSource = 'local+remote-thread-summaries-v3+managed-connections' + (cdpRows.length ? '+cdp' : ''); const remoteCounts = new Map(); - for (const thread of remotes){ - remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); - } - const remoteIds = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); - for (const thread of cdpRows){ - if (thread.location !== 'remote' || !thread.hostId) continue; - const id = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; - if (remoteIds.has(id)) continue; - remoteIds.add(id); - remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + const remoteInventory = finalizeThreadList({ + backend: cdpRows.length ? 'cdp' : 'remote-state', + limit: 10000, + threads: cdpRows.filter((thread)=>thread.location === 'remote') + }, { + limit: 10000, + remotes + }); + for (const thread of remoteInventory.threads){ + if (thread.hostId) remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); } const withCounts = [ ...byId.values() @@ -8315,10 +8600,21 @@ var __webpack_modules__ = { ]) ].sort(); return { - hosts: withCounts.map((host)=>host.hostId === 'local' ? { + hosts: withCounts.map((host)=>{ + const counted = host.hostId === 'local' ? { ...host, threadCount: localThreadCount - } : host), + } : host; + if (!counted.hostName) return counted; + const name = (0, _payload_budget_js__rspack_import_6.aA)(counted.hostName); + return { + ...counted, + hostName: name.title, + ...name.titleTruncated ? { + hostNameTruncated: true + } : {} + }; + }), hostsSource, modelProviders, modelProvidersSource, @@ -8336,25 +8632,27 @@ var __webpack_modules__ = { const appList = await this.#fallbacks.searchThreads({ query: options.query, limit, + cursor: options.cursor, modelProviders, project: options.project }); - const cdpList = await this.#tryCdpList({ + const cdpList = options.cursor ? null : await this.#tryCdpList({ limit }); const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const appMatches = new Set(appList.threads.map((thread)=>thread.threadId)); const withRemotes = finalizeThreadList(base, { limit: 10000, host, modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - remotes: this.#listRemotes() + remotes: options.cursor ? [] : this.#listRemotes() }); const needle = options.query.trim().toLowerCase(); const filtered = { ...withRemotes, query: options.query, - threads: withRemotes.threads.filter((thread)=>threadMatchesQuery(thread, needle)) + threads: withRemotes.threads.filter((thread)=>appMatches.has(thread.threadId) || threadMatchesQuery(thread, needle)) }; const result = finalizeThreadList(filtered, { limit, @@ -8366,6 +8664,7 @@ var __webpack_modules__ = { }); return result; } catch (appError) { + if (options.cursor) throw appError; const cdpList = await this.#tryCdpList({ limit }); @@ -8400,6 +8699,7 @@ var __webpack_modules__ = { const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { + if (options.cursor) throw new Error('Temporary Desktop threads do not support read cursors'); await this.#ensureCdp(); return this.#cdp.readThread({ ...options, @@ -8411,10 +8711,12 @@ var __webpack_modules__ = { return await this.#fallbacks.readThread({ threadId: options.threadId, limit, - full + full, + cursor: options.cursor }); } catch (appError) { if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; + if (options.cursor) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; const fallback = await this.#cdp.readThread({ @@ -8606,7 +8908,7 @@ var __webpack_modules__ = { if (!projectMatches(thread, project)) return false; return true; }); - const limited = filtered.slice(0, limit); + const limited = filtered.slice(0, limit).map(_payload_budget_js__rspack_import_6.eX); const result = { backend: remotes.length ? base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' : base.backend === 'app-server' ? 'app-server+remote-state' : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend : base.backend, limit, @@ -8782,6 +9084,100 @@ var __webpack_modules__ = { jv: ()=>forceLoopbackWebSocketUrl }); }, + "./src/core/chatgpt-desktop/payload-budget.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + const DESKTOP_RESULT_BUDGET_BYTES = 600 * 1024; + const DESKTOP_THREAD_TITLE_CHARS = 200; + function serializedBytes(value) { + return Buffer.byteLength(JSON.stringify(value), 'utf8'); + } + function compact(value, maxChars) { + const normalized = value.replace(/\s+/gu, ' ').trim(); + const chars = Array.from(normalized); + return { + value: chars.slice(0, maxChars).join(''), + clipped: chars.length > maxChars + }; + } + function compactThreadRow(thread) { + const title = compact(thread.title, DESKTOP_THREAD_TITLE_CHARS); + const preview = typeof thread.preview === 'string' ? compact(thread.preview, 200) : null; + const cwd = typeof thread.cwd === 'string' ? compact(thread.cwd, 2048) : null; + const project = typeof thread.project === 'string' ? compact(thread.project, 256) : null; + const hostName = typeof thread.hostName === 'string' ? compact(thread.hostName, 256) : null; + return { + ...thread, + title: title.value, + ...title.clipped ? { + titleTruncated: true + } : {}, + ...preview ? { + preview: preview.value, + ...preview.clipped ? { + previewTruncated: true + } : {} + } : {}, + ...cwd ? { + cwd: cwd.value, + ...cwd.clipped ? { + cwdTruncated: true + } : {} + } : {}, + ...project ? { + project: project.value, + ...project.clipped ? { + projectTruncated: true + } : {} + } : {}, + ...hostName ? { + hostName: hostName.value, + ...hostName.clipped ? { + hostNameTruncated: true + } : {} + } : {} + }; + } + function compactThreadTitle(title) { + const out = compact(title, DESKTOP_THREAD_TITLE_CHARS); + return { + title: out.value, + titleTruncated: out.clipped + }; + } + function minimalThreadRow(thread) { + return { + threadId: thread.threadId, + title: compact(thread.title, DESKTOP_THREAD_TITLE_CHARS).value, + titleTruncated: true, + pinned: thread.pinned, + selected: thread.selected, + kind: thread.kind, + location: thread.location, + hostId: thread.hostId, + hostName: thread.hostName, + modelProvider: thread.modelProvider, + metadataTruncated: true + }; + } + function encodePageCursor(prefix, value) { + return prefix + Buffer.from(JSON.stringify(value)).toString('base64url'); + } + function decodePageCursor(prefix, cursor) { + if (!cursor.startsWith(prefix)) throw new Error('Invalid ChatGPT Desktop page cursor'); + try { + return JSON.parse(Buffer.from(cursor.slice(prefix.length), 'base64url').toString('utf8')); + } catch { + throw new Error('Invalid ChatGPT Desktop page cursor'); + } + } + __webpack_require__.d(__webpack_exports__, { + MH: ()=>minimalThreadRow, + aA: ()=>compactThreadTitle, + eX: ()=>compactThreadRow, + i3: ()=>decodePageCursor, + oI: ()=>encodePageCursor, + sQ: ()=>serializedBytes + }); + }, "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); @@ -9219,6 +9615,7 @@ var __webpack_modules__ = { port: zod__rspack_import_4.aig().int().min(1).max(65535).optional(), query: zod__rspack_import_4.YjP().min(1).max(512), limit: zod__rspack_import_4.aig().int().min(1).max(200).default(50), + cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), host: zod__rspack_import_4.YjP().min(1).max(256).optional(), modelProvider: zod__rspack_import_4.YjP().min(1).max(256).optional(), project: zod__rspack_import_4.YjP().min(1).max(256).optional(), @@ -9232,6 +9629,7 @@ var __webpack_modules__ = { threadId, limit: zod__rspack_import_4.aig().int().min(1).max(2000).optional(), full: zod__rspack_import_4.zMY().default(false), + cursor: zod__rspack_import_4.YjP().min(1).max(4096).optional(), openTimeoutMs: zod__rspack_import_4.aig().int().min(1).max(600000).default(90000) }).strict(); const openThreadSchema = zod__rspack_import_4.Ikc({ @@ -9361,6 +9759,7 @@ var __webpack_modules__ = { return adapter.searchThreads({ query: input.query, limit: input.limit, + cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, project: input.project, @@ -9397,6 +9796,7 @@ var __webpack_modules__ = { threadId: input.threadId, limit: input.limit ?? (input.full ? 2000 : 100), full: input.full, + cursor: input.cursor, openTimeoutMs: input.openTimeoutMs })); return asResult({ @@ -10181,7 +10581,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List Desktop threads, then pass nextCursor as cursor until null. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', + description: 'List Desktop threads, then pass nextCursor as cursor until null. Pages may stop early at the MCP byte budget. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', annotations: { readOnlyHint: true }, @@ -10298,7 +10698,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop read thread', - description: 'Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Recent defaults to 100 turns; full pages up to 2000 from the start. Archived threads remain readable. complete:false means partial history; warnings preserve app-server/frame errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.', + description: 'Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Pass nextCursor back as cursor with the same threadId/full mode until complete:true. Pages stop at a byte budget; oversized turns use ordered continuation fragments with stable turnKey and field offsets, without dropping text. Archived threads remain readable. Warnings explain partial pages or app-server errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.', annotations: { readOnlyHint: true }, @@ -10321,6 +10721,10 @@ var __webpack_modules__ = { limit: { type: 'number' }, + cursor: { + type: 'string', + description: 'Opaque nextCursor from the prior read page. Keep threadId and full unchanged.' + }, full: { type: 'boolean', description: 'When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.' @@ -10357,7 +10761,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop search threads', - description: 'Search Desktop thread metadata by case-insensitive substring. Dynamic hostId/hostName, modelProvider, and project filters apply. Search scans bounded app-server pages and reports warnings if incomplete; use list_threads cursor for exhaustive paging. Remote results identify hostId and cannot be read on this Mac.', + description: 'Search full Desktop thread metadata by case-insensitive substring. Display titles are capped at 200 characters with titleTruncated:true. Pass nextCursor as cursor with unchanged query and filters to retrieve all matches. Dynamic hostId/hostName, modelProvider, and project filters apply. Remote results identify hostId and cannot be read on this Mac.', annotations: { readOnlyHint: true }, @@ -10379,6 +10783,10 @@ var __webpack_modules__ = { default: 50, description: 'Maximum matches.' }, + cursor: { + type: 'string', + description: 'Opaque nextCursor from the previous search page; keep query and filters unchanged.' + }, host: { type: 'string', description: 'Any string filter for machine/location. Reserved: "all" (default), "local". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.' @@ -59745,7 +60153,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "List Desktop threads, then pass nextCursor as cursor until null. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.", + "description": "List Desktop threads, then pass nextCursor as cursor until null. Pages may stop early at the MCP byte budget. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -59830,10 +60238,14 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Recent defaults to 100 turns; full pages up to 2000 from the start. Archived threads remain readable. complete:false means partial history; warnings preserve app-server/frame errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.", + "description": "Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Pass nextCursor back as cursor with the same threadId/full mode until complete:true. Pages stop at a byte budget; oversized turns use ordered continuation fragments with stable turnKey and field offsets, without dropping text. Archived threads remain readable. Warnings explain partial pages or app-server errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "cursor": { + "description": "Opaque nextCursor from the prior read page. Keep threadId and full unchanged.", + "type": "string" + }, "full": { "description": "When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.", "type": "boolean" @@ -59873,10 +60285,14 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "Search Desktop thread metadata by case-insensitive substring. Dynamic hostId/hostName, modelProvider, and project filters apply. Search scans bounded app-server pages and reports warnings if incomplete; use list_threads cursor for exhaustive paging. Remote results identify hostId and cannot be read on this Mac.", + "description": "Search full Desktop thread metadata by case-insensitive substring. Display titles are capped at 200 characters with titleTruncated:true. Pass nextCursor as cursor with unchanged query and filters to retrieve all matches. Dynamic hostId/hostName, modelProvider, and project filters apply. Remote results identify hostId and cannot be read on this Mac.", "inputJsonSchema": { "additionalProperties": false, "properties": { + "cursor": { + "description": "Opaque nextCursor from the previous search page; keep query and filters unchanged.", + "type": "string" + }, "groupBy": { "description": "When \"host\", also return groups[] keyed by host (grouping mode, not a host id).", "enum": [ diff --git a/artifact/skills/chatgpt-desktop/SKILL.md b/artifact/skills/chatgpt-desktop/SKILL.md index 07a024b..5c32b3b 100644 --- a/artifact/skills/chatgpt-desktop/SKILL.md +++ b/artifact/skills/chatgpt-desktop/SKILL.md @@ -19,12 +19,18 @@ another machine. host name from a project label. Managed SSH hosts may have no threads. 3. Use `chatgpt_desktop_list_threads` with `host`, `modelProvider`, or `project` as needed. Pass `nextCursor` back as `cursor` with the same filters until it - is `null`. `chatgpt_desktop_search_threads` scans metadata for a substring; - inspect `warnings` if a source failed or the scan was capped. + is `null`. Pages can stop before `limit` to stay under the MCP document cap. + `chatgpt_desktop_search_threads` also accepts `cursor`; keep its query and + filters unchanged. Search matches the full title even when the display row + has a 200-character `title` and `titleTruncated: true`. 4. Read with `chatgpt_desktop_read_thread`. `full: false` gets the recent tail; - `full: true` pages from the start (up to 2,000 turns unless `limit` is set). - Check `complete` and `warnings` before treating it as full history. A turn - may contain both `userText` and `assistantText`. + `full: true` pages chronologically from the start. Pass `nextCursor` back + as `cursor` with the same thread ID and `full` value until `complete: true`. + The byte budget can stop before `limit`. An oversized turn is returned as + ordered fragments with one stable `turnKey`; use `continuation.field`, + `offsetChars`, and `totalChars` to reassemble `text`, `userText`, and + `assistantText`. `textTruncated: true` signals a fragment, not missing text. + Check `complete` and `warnings` before treating a page as full history. Durable local IDs are `local:` (a bare conversation ID also works). `local:client-new-thread:*` is temporary and works only while that diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index 2e508b3..cd49955 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -39,6 +39,7 @@ gbot chatgpt-desktop threads --host --model-provider gbot chatgpt-desktop threads --project gbot chatgpt-desktop search "launch" --host all gbot chatgpt-desktop read +gbot chatgpt-desktop read --full --cursor gbot chatgpt-desktop send --thread-id "hello" gbot chatgpt-desktop send --thread-id --unarchive "hello" gbot chatgpt-desktop send --project "new chat in project" @@ -89,7 +90,11 @@ DOM (tool calls, reasoning, timing, and sometimes more turns). 3. Page history with `thread/turns/list` (`itemsView: "full"`, `cursor` / `nextCursor`); `thread/items/list` is a fallback only for unsupported RPCs. Recent reads request descending pages and return chronological turns; - `full` reads request ascending pages, bounded by `limit`. Empty history is valid. + `full` reads request ascending pages, bounded by `limit`. Return pages below + the Agent Bundle 1 MiB document cap. Pass `nextCursor` back as `cursor` until + `complete: true`. A large turn uses ordered `continuation` fragments with + a stable `turnKey` and field offsets, so all text remains retrievable. + Empty history is valid. 4. **Do not** `thread/resume` for reads — resume attaches a live session `thread/list` filters to the current model provider by default. Pass @@ -102,6 +107,10 @@ Surfaced list fields: `id`, `name`, `preview`, `cwd`, `createdAt` / `updatedAt` (unix s), `section {id,name}` (Pinned → `pinned: true`), `projectId`, `status`, `modelProvider`, `model`, `originator`. `archived` is a list filter, not a field. +List and search pages can stop before `limit` to stay under the document cap. +Display titles collapse whitespace and stop at 200 characters with +`titleTruncated: true`; search still matches the full source title. Pass +`nextCursor` back with unchanged filters and query. ### Host and modelProvider filters (separate) diff --git a/src/cli/chatgpt-desktop/read.tsx b/src/cli/chatgpt-desktop/read.tsx index 3ae852e..6b60cb4 100644 --- a/src/cli/chatgpt-desktop/read.tsx +++ b/src/cli/chatgpt-desktop/read.tsx @@ -17,6 +17,7 @@ export const config = { additionalProperties: false, properties: { full: { default: false, type: 'boolean' }, + cursor: { description: 'Opaque nextCursor from the prior read page', type: 'string' }, limit: { description: 'Recent default 100; full default 2000', type: 'number' }, openTimeoutMs: { default: 90000, type: 'number' }, port: { type: 'number' }, @@ -31,6 +32,7 @@ export const config = { export const inputSchema = z .object({ full: z.boolean().default(false), + cursor: z.string().min(1).max(4096).optional(), limit: z.number().int().min(1).max(2000).optional(), openTimeoutMs: z.number().int().min(1).max(600_000).default(90_000), port: z.number().int().min(1).max(65535).optional(), diff --git a/src/cli/chatgpt-desktop/search.tsx b/src/cli/chatgpt-desktop/search.tsx index 53b17d2..c5ff728 100644 --- a/src/cli/chatgpt-desktop/search.tsx +++ b/src/cli/chatgpt-desktop/search.tsx @@ -27,6 +27,7 @@ export const config = { type: 'string', }, limit: { default: 50, description: 'Max matches (1-200)', type: 'number' }, + cursor: { description: 'Opaque nextCursor from a prior search page', type: 'string' }, modelProvider: { description: 'Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.', @@ -46,6 +47,7 @@ export const inputSchema = z groupBy: z.literal('host').optional(), host: z.string().min(1).max(256).optional(), limit: z.number().int().min(1).max(200).default(50), + cursor: z.string().min(1).max(4096).optional(), modelProvider: z.string().min(1).max(256).optional(), project: z.string().min(1).max(256).optional(), port: z.number().int().min(1).max(65535).optional(), diff --git a/src/core/chatgpt-desktop/adapter.ts b/src/core/chatgpt-desktop/adapter.ts index 919bdab..dd0b4b0 100644 --- a/src/core/chatgpt-desktop/adapter.ts +++ b/src/core/chatgpt-desktop/adapter.ts @@ -30,6 +30,7 @@ export interface ChatGptDesktopAdapter { searchThreads?(options: { query: string; limit?: number; + cursor?: string; /** Any string; see list_hosts. Not an enum. */ host?: string; /** Any modelProvider id; see list_hosts. Not an enum. */ @@ -48,6 +49,7 @@ export interface ChatGptDesktopAdapter { threadId: string; limit?: number; full?: boolean; + cursor?: string; openTimeoutMs?: number; }): Promise; /** diff --git a/src/core/chatgpt-desktop/app-server-fallback.ts b/src/core/chatgpt-desktop/app-server-fallback.ts index 0447b70..efa7bd0 100644 --- a/src/core/chatgpt-desktop/app-server-fallback.ts +++ b/src/core/chatgpt-desktop/app-server-fallback.ts @@ -18,6 +18,15 @@ import { } from '../codex-bridge.js'; import { RemoteThreadNotLoadedError } from './errors.js'; import { findRemoteThread, findRemoteThreadHostId } from './remote-threads.js'; +import { + DESKTOP_RESULT_BUDGET_BYTES, + compactThreadRow, + compactThreadTitle, + decodePageCursor, + encodePageCursor, + minimalThreadRow, + serializedBytes, +} from './payload-budget.js'; import { requireAppServerThreadId, toDesktopThreadId, @@ -30,6 +39,11 @@ import type { ReadThreadResult, } from './types.js'; +const LIST_PAGE_PREFIX = 'desktop-list-v1:'; +const SEARCH_PAGE_PREFIX = 'desktop-search-v1:'; +const READ_PAGE_PREFIX = 'desktop-read-v1:'; +type ListPageCursor = { cursor: string | null; skip: number; fetchLimit: number }; + export async function appServerListThreads({ limit = 50, cursor, @@ -39,55 +53,114 @@ export async function appServerListThreads({ cursor?: string; modelProviders?: string[]; } = {}): Promise { - const out = await listCodexThreads({ limit, cursor, modelProviders }); - return { - backend: 'app-server', - limit: out.limit, - nextCursor: out.nextCursor ?? null, - threads: out.threads.map(mapListedThread), + let sourceCursor = cursor; + let skip = 0; + let fetchLimit = Math.min(limit, 25); + if (cursor?.startsWith(LIST_PAGE_PREFIX)) { + const state = decodePageCursor(LIST_PAGE_PREFIX, cursor); + if (!Number.isSafeInteger(state.skip) || state.skip < 1 + || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 + || (state.cursor !== null && typeof state.cursor !== 'string')) { + throw new Error('Invalid ChatGPT Desktop list page cursor'); + } + sourceCursor = state.cursor ?? undefined; + skip = state.skip; + fetchLimit = state.fetchLimit; + } + const out = await listCodexThreads({ limit: fetchLimit, cursor: sourceCursor, modelProviders }); + if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); + const base = { + backend: 'app-server' as const, + limit, modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, }; + const threads: ChatGptDesktopThread[] = []; + let consumed = skip; + for (const raw of out.threads.slice(skip)) { + if (threads.length >= limit) break; + let row = compactThreadRow(mapListedThread(raw)); + const probe = { ...base, threads: [...threads, row], nextCursor: LIST_PAGE_PREFIX, exitCode: 0 }; + if (serializedBytes(probe) > DESKTOP_RESULT_BUDGET_BYTES) { + if (threads.length) break; + row = minimalThreadRow(row); + if (serializedBytes({ ...base, threads: [row], nextCursor: LIST_PAGE_PREFIX, exitCode: 0 }) > DESKTOP_RESULT_BUDGET_BYTES) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + threads.push(row); + consumed++; + } + const nextCursor = consumed < out.threads.length + ? encodePageCursor(LIST_PAGE_PREFIX, { cursor: sourceCursor ?? null, skip: consumed, fetchLimit }) + : out.nextCursor ?? null; + return { + ...base, threads, nextCursor, + ...(consumed < out.threads.length ? { warnings: ['List page stopped at the MCP byte budget; continue with nextCursor'] } : {}), + }; } export async function appServerSearchThreads({ query, limit = 50, + cursor, modelProviders = [], project, }: { query: string; limit?: number; + cursor?: string; modelProviders?: string[]; project?: string; }): Promise { const needle = query.trim().toLowerCase(); if (!needle) { - return appServerListThreads({ limit, modelProviders }); + return appServerListThreads({ limit, cursor, modelProviders }); } const matched: ChatGptDesktopThread[] = []; - let cursor: string | undefined; - let exhausted = false; - for (let page = 0; page < 400 && matched.length < limit; page++) { - const out = await listCodexThreads({ limit: 25, cursor, modelProviders }); - for (const thread of out.threads) { - const mapped = mapListedThread(thread); - if (threadMatchesQuery(mapped, needle) - && (!project || [mapped.project, mapped.projectId].some((value) => - typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase())))) matched.push(mapped); - if (matched.length >= limit) break; + let sourceCursor: string | undefined; + let skip = 0; + if (cursor) { + const state = decodePageCursor<{ cursor: string | null; skip: number; query: string; project?: string; modelProviders: string[] }>(SEARCH_PAGE_PREFIX, cursor); + if (state.query !== query || state.project !== project + || JSON.stringify(state.modelProviders) !== JSON.stringify(modelProviders) + || !Number.isSafeInteger(state.skip) || state.skip < 0) { + throw new Error('Search cursor does not match this query and its filters'); } - if (out.nextCursor == null || typeof out.nextCursor !== 'string') { exhausted = true; break; } - cursor = out.nextCursor; + sourceCursor = state.cursor ?? undefined; + skip = state.skip; } - return { - backend: 'app-server', - limit, - query, - nextCursor: null, - threads: matched.slice(0, limit), - modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, - ...(!exhausted && matched.length < limit ? { warnings: ['Search stopped after 400 app-server pages; results may be incomplete'] } : {}), - }; + const pageCursor = (rpcCursor: string | undefined, offset: number) => encodePageCursor(SEARCH_PAGE_PREFIX, { + cursor: rpcCursor ?? null, skip: offset, query, project, modelProviders, + }); + const base = { backend: 'app-server' as const, limit, query, + modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; + for (let page = 0; page < 400; page++) { + const out = await listCodexThreads({ limit: 25, cursor: sourceCursor, modelProviders }); + if (skip > out.threads.length) throw new Error('ChatGPT Desktop search cursor is stale'); + for (let index = skip; index < out.threads.length; index++) { + const mapped = mapListedThread(out.threads[index]); + if (!threadMatchesQuery(mapped, needle) + || (project && ![mapped.project, mapped.projectId].some((value) => + typeof value === 'string' && value.toLowerCase().includes(project.trim().toLowerCase())))) continue; + let row = compactThreadRow(mapped); + if (serializedBytes({ ...base, threads: [...matched, row], nextCursor: SEARCH_PAGE_PREFIX, exitCode: 0 }) > DESKTOP_RESULT_BUDGET_BYTES) { + if (matched.length) return { ...base, threads: matched, nextCursor: pageCursor(sourceCursor, index), + warnings: ['Search page stopped at the MCP byte budget; continue with nextCursor'] }; + row = minimalThreadRow(row); + } + matched.push(row); + if (matched.length >= limit) { + const nextCursor = index + 1 < out.threads.length + ? pageCursor(sourceCursor, index + 1) : out.nextCursor ? pageCursor(out.nextCursor, 0) : null; + return { ...base, threads: matched, nextCursor }; + } + } + if (out.nextCursor == null) return { ...base, threads: matched, nextCursor: null }; + sourceCursor = out.nextCursor; + skip = 0; + } + return { ...base, threads: matched, nextCursor: pageCursor(sourceCursor, 0), + warnings: ['Search stopped after 400 app-server pages; continue with nextCursor'] }; } export type ModelProvidersDiscovery = { @@ -126,10 +199,12 @@ export async function appServerReadThread({ threadId, limit, full = false, + cursor, }: { threadId: string; limit?: number; full?: boolean; + cursor?: string; }): Promise { // Prefixed `local:` ids fail with `invalid thread id` — always strip first. limit ??= full ? 2000 : 100; @@ -140,7 +215,7 @@ export async function appServerReadThread({ if (remote) { // Still try local app-server in case the thread was also loaded locally. try { - return await readLocalThread(bare, { limit, full }); + return await readLocalThread(bare, { limit, full, cursor }); } catch (error) { if (isThreadNotLoaded(error) || isUnknownThread(error)) { throw new RemoteThreadNotLoadedError(bare, remote.hostId, remote.hostName); @@ -150,7 +225,7 @@ export async function appServerReadThread({ } try { - return await readLocalThread(bare, { limit, full }); + return await readLocalThread(bare, { limit, full, cursor }); } catch (error) { throw maybeRemoteThreadError(error, bare); } @@ -174,12 +249,12 @@ export async function appServerUnarchiveThread(threadId: string): Promise async function readLocalThread( bare: string, - { limit, full }: { limit: number; full: boolean }, + { limit, full, cursor }: { limit: number; full: boolean; cursor?: string }, ): Promise { const { client } = await openCodexSession(); try { const meta = await readThreadMetadata(client, bare); - const { turns, complete } = await listTurnsFull(client, bare, { limit, full }); + const { turns, complete, nextCursor } = await listTurnsFull(client, bare, { limit, full, cursor, title: meta.title }); return { threadId: toDesktopThreadId(bare), turns, @@ -187,7 +262,9 @@ async function readLocalThread( limit, full, complete, - title: meta.title, + nextCursor, + ...(complete ? {} : { warnings: ['Read page stopped before the end of the thread; continue with nextCursor to retrieve every turn and text fragment'] }), + ...(meta.title ? compactThreadTitle(meta.title) : {}), cwd: meta.cwd, status: meta.status, modelProvider: meta.modelProvider, @@ -327,47 +404,134 @@ async function readThreadMetadata( async function listTurnsFull( client: AppServerClient, threadId: string, - { limit, full }: { limit: number; full: boolean }, -): Promise<{ turns: ChatGptDesktopTurn[]; complete: boolean }> { - const collected: unknown[] = []; - let cursor: string | undefined; + { limit, full, cursor, title }: { limit: number; full: boolean; cursor?: string; title?: string }, +): Promise<{ turns: ChatGptDesktopTurn[]; complete: boolean; nextCursor: string | null }> { + type ReadCursor = { threadId: string; full: boolean; rpcCursor: string | null; skip: number; field?: 'text' | 'userText' | 'assistantText'; offset?: number }; + const state = cursor ? decodePageCursor(READ_PAGE_PREFIX, cursor) : null; + if (state && (state.threadId !== threadId || state.full !== full || !Number.isSafeInteger(state.skip) || state.skip < 0 + || (state.rpcCursor !== null && typeof state.rpcCursor !== 'string') + || (state.field !== undefined && !['text', 'userText', 'assistantText'].includes(state.field)) + || (state.offset !== undefined && (!Number.isSafeInteger(state.offset) || state.offset < 0)))) { + throw new Error('Read cursor does not match this thread or mode'); + } + let rpcCursor = state?.rpcCursor ?? undefined; + let skip = state?.skip ?? 0; + let fragmentField = state?.field; + let fragmentOffset = state?.offset ?? 0; let itemsView = true; let method = 'thread/turns/list'; const seen = new Set(); - let complete = false; - while (collected.length < limit) { + const turns: ChatGptDesktopTurn[] = []; + const pageCursor = (source: string | undefined, index: number, field?: ReadCursor['field'], offset?: number) => + encodePageCursor(READ_PAGE_PREFIX, { threadId, full, rpcCursor: source ?? null, skip: index, + ...(field ? { field, offset } : {}) }); + const fits = (candidate: ChatGptDesktopTurn) => serializedBytes({ threadId, turns: [...turns, candidate], + backend: 'app-server', limit, full, complete: false, nextCursor: READ_PAGE_PREFIX, + title: title ? compactThreadTitle(title).title : undefined, + warnings: ['Read page stopped before the end of the thread; continue with nextCursor to retrieve every turn and text fragment'], + exitCode: 0 }) <= DESKTOP_RESULT_BUDGET_BYTES; + while (turns.length < limit) { let result: { data?: unknown[]; nextCursor?: string | null }; try { result = await client.request(method, { threadId, - limit: Math.min(10, limit - collected.length), + limit: Math.min(10, Math.max(limit - turns.length, skip + 1)), sortDirection: full ? 'asc' : 'desc', ...(method === 'thread/turns/list' && itemsView ? { itemsView: 'full' } : {}), - ...(cursor !== undefined ? { cursor } : {}), + ...(rpcCursor !== undefined ? { cursor: rpcCursor } : {}), }) as typeof result; } catch (error) { const code = (error as { rpc?: { code?: number } })?.rpc?.code; - if (collected.length === 0 && code === -32602 && itemsView) { + if (turns.length === 0 && code === -32602 && itemsView) { itemsView = false; continue; } - if (collected.length === 0 && code === -32601 && method === 'thread/turns/list') { + if (turns.length === 0 && code === -32601 && method === 'thread/turns/list') { method = 'thread/items/list'; continue; } throw maybeRemoteThreadError(error, threadId); } if (!Array.isArray(result?.data)) throw new Error(`${method} missing data array for ${threadId}`); - collected.push(...result.data); - if (result.nextCursor == null) { complete = true; break; } + if (skip > result.data.length) throw new Error('Read cursor is stale'); + const pageTurns = normalizeTurns(result.data); + for (let index = skip; index < pageTurns.length; index++) { + const turn = pageTurns[index]; + if (!fragmentField && turns.length && !fits(turn)) { + return { turns: chronologicalPage(turns, full), complete: false, + nextCursor: pageCursor(rpcCursor, index) }; + } + if (!fragmentField && fits(turn)) { + turns.push(turn); + } else { + const fields = (['text', 'userText', 'assistantText'] as const).filter((field) => + typeof turn[field] === 'string' && turn[field]!.length > 0); + let fieldIndex = fragmentField ? fields.indexOf(fragmentField) : 0; + if (fieldIndex < 0) throw new Error('Read fragment cursor is stale'); + for (; fieldIndex < fields.length; fieldIndex++) { + const field = fields[fieldIndex]; + const value = turn[field]!; + let offset = field === fragmentField ? fragmentOffset : 0; + if (offset > value.length) throw new Error('Read fragment cursor is stale'); + while (offset < value.length) { + let size = Math.min(value.length - offset, 32_768); + let fragment: ChatGptDesktopTurn; + do { + let end = offset + size; + if (end < value.length && /[\uD800-\uDBFF]/u.test(value[end - 1])) end--; + const chunk = value.slice(offset, end); + fragment = { turnKey: turn.turnKey, role: turn.role, text: field === 'text' ? chunk : '', + ...(field === 'userText' ? { userText: chunk } : {}), + ...(field === 'assistantText' ? { assistantText: chunk } : {}), + startedAt: turn.startedAt, endedAt: turn.endedAt, textTruncated: true, + continuation: { field, offsetChars: offset, totalChars: value.length, + fieldComplete: end === value.length, + turnComplete: end === value.length && fieldIndex === fields.length - 1 } }; + if (fits(fragment)) { size = end - offset; break; } + size = Math.floor(size / 2); + } while (size > 0); + if (size === 0) { + if (turns.length) return { turns: chronologicalPage(turns, full), complete: false, + nextCursor: pageCursor(rpcCursor, index, field, offset) }; + throw new Error('Read fragment metadata exceeds the MCP result byte budget'); + } + turns.push(fragment); + offset += size; + if (turns.length >= limit || offset < value.length && !fits({ ...fragment, text: 'x'.repeat(32_768) })) { + return { turns: chronologicalPage(turns, full), complete: false, + nextCursor: pageCursor(rpcCursor, index, field, offset) }; + } + } + } + fragmentField = undefined; + fragmentOffset = 0; + } + if (turns.length >= limit) { + const nextCursor = index + 1 < pageTurns.length ? pageCursor(rpcCursor, index + 1) + : result.nextCursor ? pageCursor(result.nextCursor, 0) : null; + return { turns: chronologicalPage(turns, full), complete: nextCursor === null, nextCursor }; + } + } + if (result.nextCursor == null) return { turns: chronologicalPage(turns, full), complete: true, nextCursor: null }; if (typeof result.nextCursor !== 'string' || !result.nextCursor || seen.has(result.nextCursor)) { throw new Error(`${method} returned an invalid or repeated cursor`); } seen.add(result.nextCursor); - cursor = result.nextCursor; + rpcCursor = result.nextCursor; + skip = 0; + } + return { turns: chronologicalPage(turns, full), complete: false, nextCursor: pageCursor(rpcCursor, skip) }; +} + +function chronologicalPage(turns: ChatGptDesktopTurn[], full: boolean): ChatGptDesktopTurn[] { + if (full) return turns; + const groups: ChatGptDesktopTurn[][] = []; + for (const turn of turns) { + const last = groups.at(-1); + if (last?.[0]?.turnKey === turn.turnKey) last.push(turn); + else groups.push([turn]); } - const turns = normalizeTurns(collected.slice(0, limit)); - return { turns: full ? turns : turns.reverse(), complete }; + return groups.reverse().flat(); } function normalizeTurns(raw: unknown[]): ChatGptDesktopTurn[] { diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index 4045450..4e5a72e 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -11,6 +11,7 @@ import { import { ArchivedThreadError, CdpUnreachableError, NotImplementedError, RemoteThreadNotLoadedError } from './errors.js'; import { resolveCdpPort } from './loopback.js'; import { findRemoteThread, listDiscoveredHosts, listRemoteThreadsFromState } from './remote-threads.js'; +import { compactThreadRow, compactThreadTitle, DESKTOP_RESULT_BUDGET_BYTES, serializedBytes } from './payload-budget.js'; import { isTemporaryDesktopThreadId, threadIdsEquivalent, @@ -149,7 +150,16 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { }, { limit: 10_000, host, modelProvider: options.modelProvider, project: options.project, remotes }); const offset = remoteOffset ?? 0; if (remoteOffset !== null || remoteInventory.threads.length >= limit) { - const page = remoteInventory.threads.slice(offset, offset + limit); + const page: ChatGptDesktopThread[] = []; + for (const thread of remoteInventory.threads.slice(offset, offset + limit)) { + const row = compactThreadRow(thread); + if (serializedBytes({ ...remoteInventory, threads: [...page, row], nextCursor: REMOTE_PAGE_CURSOR, + ...(options.groupBy === 'host' ? { groups: groupThreadsByHost([...page, row]) } : {}) }) > DESKTOP_RESULT_BUDGET_BYTES) { + if (!page.length) throw new Error('ChatGPT Desktop remote thread row exceeds the MCP result byte budget'); + break; + } + page.push(row); + } const nextOffset = offset + page.length; const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; @@ -244,16 +254,12 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { // Recount remotes from the parsed summary rows for accuracy. const remoteCounts = new Map(); - for (const thread of remotes) { - remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); - } - const remoteIds = new Set(remotes.map((thread) => toAppServerThreadId(thread.threadId) ?? thread.threadId)); - for (const thread of cdpRows) { - if (thread.location !== 'remote' || !thread.hostId) continue; - const id = toAppServerThreadId(thread.threadId) ?? thread.threadId; - if (remoteIds.has(id)) continue; - remoteIds.add(id); - remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); + const remoteInventory = finalizeThreadList({ + backend: cdpRows.length ? 'cdp' : 'remote-state', limit: 10_000, + threads: cdpRows.filter((thread) => thread.location === 'remote'), + }, { limit: 10_000, remotes }); + for (const thread of remoteInventory.threads) { + if (thread.hostId) remoteCounts.set(thread.hostId, (remoteCounts.get(thread.hostId) ?? 0) + 1); } const withCounts = [...byId.values()] .map((host) => @@ -291,7 +297,13 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { ...remotes.map((thread) => thread.modelProvider).filter((value): value is string => Boolean(value)), ])].sort(); return { - hosts: withCounts.map((host) => host.hostId === 'local' ? { ...host, threadCount: localThreadCount } : host), + hosts: withCounts.map((host) => { + const counted = host.hostId === 'local' ? { ...host, threadCount: localThreadCount } : host; + if (!counted.hostName) return counted; + const name = compactThreadTitle(counted.hostName); + return { ...counted, hostName: name.title, + ...(name.titleTruncated ? { hostNameTruncated: true } : {}) }; + }), hostsSource, modelProviders, modelProvidersSource, @@ -305,6 +317,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { async searchThreads(options: { query: string; limit?: number; + cursor?: string; host?: string; modelProvider?: string; project?: string; @@ -317,23 +330,25 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { const appList = await this.#fallbacks.searchThreads({ query: options.query, limit, + cursor: options.cursor, modelProviders, project: options.project, }); - const cdpList = await this.#tryCdpList({ limit }); + const cdpList = options.cursor ? null : await this.#tryCdpList({ limit }); const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const appMatches = new Set(appList.threads.map((thread) => thread.threadId)); const withRemotes = finalizeThreadList(base, { limit: 10_000, host, modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - remotes: this.#listRemotes(), + remotes: options.cursor ? [] : this.#listRemotes(), }); const needle = options.query.trim().toLowerCase(); const filtered = { ...withRemotes, query: options.query, - threads: withRemotes.threads.filter((thread) => threadMatchesQuery(thread, needle)), + threads: withRemotes.threads.filter((thread) => appMatches.has(thread.threadId) || threadMatchesQuery(thread, needle)), }; const result = finalizeThreadList(filtered, { limit, @@ -345,6 +360,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { }); return result; } catch (appError) { + if (options.cursor) throw appError; const cdpList = await this.#tryCdpList({ limit }); const remotes = this.#listRemotes(); if (!cdpList && !remotes.length) throw appError; @@ -370,12 +386,14 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { threadId: string; limit?: number; full?: boolean; + cursor?: string; openTimeoutMs?: number; }): Promise { const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; if (isTemporaryDesktopThreadId(options.threadId)) { + if (options.cursor) throw new Error('Temporary Desktop threads do not support read cursors'); await this.#ensureCdp(); return this.#cdp.readThread({ ...options, limit, full }); } @@ -385,9 +403,11 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { threadId: options.threadId, limit, full, + cursor: options.cursor, }); } catch (appError) { if (appError instanceof RemoteThreadNotLoadedError) throw appError; + if (options.cursor) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; const fallback = await this.#cdp.readThread({ ...options, limit, full }); @@ -606,7 +626,7 @@ export function finalizeThreadList( if (!projectMatches(thread, project)) return false; return true; }); - const limited = filtered.slice(0, limit); + const limited = filtered.slice(0, limit).map(compactThreadRow); const result: ListThreadsResult = { backend: remotes.length ? (base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' diff --git a/src/core/chatgpt-desktop/payload-budget.ts b/src/core/chatgpt-desktop/payload-budget.ts new file mode 100644 index 0000000..f4f4cff --- /dev/null +++ b/src/core/chatgpt-desktop/payload-budget.ts @@ -0,0 +1,67 @@ +import type { ChatGptDesktopThread } from './types.js'; + +/** Agent Bundle rejects documents above 1 MiB; leave room for its envelope. */ +export const DESKTOP_RESULT_BUDGET_BYTES = 600 * 1024; +export const DESKTOP_THREAD_TITLE_CHARS = 200; + +export function serializedBytes(value: unknown): number { + return Buffer.byteLength(JSON.stringify(value), 'utf8'); +} + +function compact(value: string, maxChars: number): { value: string; clipped: boolean } { + const normalized = value.replace(/\s+/gu, ' ').trim(); + const chars = Array.from(normalized); + return { value: chars.slice(0, maxChars).join(''), clipped: chars.length > maxChars }; +} + +/** Compact display metadata after search has matched the original full text. */ +export function compactThreadRow(thread: ChatGptDesktopThread): ChatGptDesktopThread { + const title = compact(thread.title, DESKTOP_THREAD_TITLE_CHARS); + const preview = typeof thread.preview === 'string' ? compact(thread.preview, 200) : null; + const cwd = typeof thread.cwd === 'string' ? compact(thread.cwd, 2048) : null; + const project = typeof thread.project === 'string' ? compact(thread.project, 256) : null; + const hostName = typeof thread.hostName === 'string' ? compact(thread.hostName, 256) : null; + return { + ...thread, + title: title.value, + ...(title.clipped ? { titleTruncated: true } : {}), + ...(preview ? { preview: preview.value, ...(preview.clipped ? { previewTruncated: true } : {}) } : {}), + ...(cwd ? { cwd: cwd.value, ...(cwd.clipped ? { cwdTruncated: true } : {}) } : {}), + ...(project ? { project: project.value, ...(project.clipped ? { projectTruncated: true } : {}) } : {}), + ...(hostName ? { hostName: hostName.value, ...(hostName.clipped ? { hostNameTruncated: true } : {}) } : {}), + }; +} + +export function compactThreadTitle(title: string): { title: string; titleTruncated: boolean } { + const out = compact(title, DESKTOP_THREAD_TITLE_CHARS); + return { title: out.value, titleTruncated: out.clipped }; +} + +export function minimalThreadRow(thread: ChatGptDesktopThread): ChatGptDesktopThread { + return { + threadId: thread.threadId, + title: compact(thread.title, DESKTOP_THREAD_TITLE_CHARS).value, + titleTruncated: true, + pinned: thread.pinned, + selected: thread.selected, + kind: thread.kind, + location: thread.location, + hostId: thread.hostId, + hostName: thread.hostName, + modelProvider: thread.modelProvider, + metadataTruncated: true, + }; +} + +export function encodePageCursor(prefix: string, value: object): string { + return prefix + Buffer.from(JSON.stringify(value)).toString('base64url'); +} + +export function decodePageCursor(prefix: string, cursor: string): T { + if (!cursor.startsWith(prefix)) throw new Error('Invalid ChatGPT Desktop page cursor'); + try { + return JSON.parse(Buffer.from(cursor.slice(prefix.length), 'base64url').toString('utf8')) as T; + } catch { + throw new Error('Invalid ChatGPT Desktop page cursor'); + } +} diff --git a/src/core/chatgpt-desktop/routes.ts b/src/core/chatgpt-desktop/routes.ts index de21167..d87d75a 100644 --- a/src/core/chatgpt-desktop/routes.ts +++ b/src/core/chatgpt-desktop/routes.ts @@ -40,6 +40,7 @@ export const searchThreadsSchema = z port: z.number().int().min(1).max(65535).optional(), query: z.string().min(1).max(512), limit: z.number().int().min(1).max(200).default(50), + cursor: z.string().min(1).max(4096).optional(), /** Any string; see `chatgpt_desktop_list_hosts`. Not an enum. */ host: z.string().min(1).max(256).optional(), /** Any modelProvider id; see `chatgpt_desktop_list_hosts`. Not an enum. */ @@ -61,6 +62,7 @@ export const readThreadSchema = z threadId, limit: z.number().int().min(1).max(2000).optional(), full: z.boolean().default(false), + cursor: z.string().min(1).max(4096).optional(), openTimeoutMs: z.number().int().min(1).max(600_000).default(90_000), }) .strict(); @@ -205,6 +207,7 @@ export async function searchThreadsOperation( return adapter.searchThreads({ query: input.query, limit: input.limit, + cursor: input.cursor, host: input.host, modelProvider: input.modelProvider, project: input.project, @@ -242,6 +245,7 @@ export async function readThreadOperation( threadId: input.threadId, limit: input.limit ?? (input.full ? 2000 : 100), full: input.full, + cursor: input.cursor, openTimeoutMs: input.openTimeoutMs, }), ); diff --git a/src/core/chatgpt-desktop/types.ts b/src/core/chatgpt-desktop/types.ts index 39921e6..b0716a1 100644 --- a/src/core/chatgpt-desktop/types.ts +++ b/src/core/chatgpt-desktop/types.ts @@ -4,6 +4,7 @@ export type ChatGptDesktopTarget = { readonly targetId: string; readonly type: string; readonly title: string; + readonly titleTruncated?: boolean; readonly url: string; readonly attached: boolean; }; @@ -18,6 +19,7 @@ export type ChatGptDesktopThreadSection = { export type ChatGptDesktopThread = { readonly threadId: string; readonly title: string; + readonly titleTruncated?: boolean; readonly pinned: boolean; /** CDP-only: currently selected sidebar row. */ readonly selected: boolean; @@ -25,7 +27,9 @@ export type ChatGptDesktopThread = { /** Project folder name when known (CDP sidebar or app-server projectId). */ readonly project?: string; readonly preview?: string; + readonly previewTruncated?: boolean; readonly cwd?: string | null; + readonly cwdTruncated?: boolean; readonly createdAt?: number | null; readonly updatedAt?: number | null; readonly section?: ChatGptDesktopThreadSection | null; @@ -40,6 +44,9 @@ export type ChatGptDesktopThread = { readonly hostId?: string | null; /** Friendly host / env name from Desktop global state when known. */ readonly hostName?: string | null; + readonly projectTruncated?: boolean; + readonly hostNameTruncated?: boolean; + readonly metadataTruncated?: boolean; }; export type ChatGptDesktopHostGroup = { @@ -58,6 +65,15 @@ export type ChatGptDesktopTurn = { readonly userText?: string; /** Final assistant markdown when present on the same turn. */ readonly assistantText?: string; + /** A large turn is split into ordered fragments sharing this stable turnKey. */ + readonly textTruncated?: boolean; + readonly continuation?: { + readonly field: 'text' | 'userText' | 'assistantText'; + readonly offsetChars: number; + readonly totalChars: number; + readonly fieldComplete: boolean; + readonly turnComplete: boolean; + }; readonly startedAt?: number | null; readonly endedAt?: number | null; }; @@ -101,6 +117,7 @@ export type ListHostsResult = { readonly hosts: readonly { readonly hostId: string; readonly hostName: string | null; + readonly hostNameTruncated?: boolean; readonly location: ChatGptDesktopThreadLocation; readonly threadCount: number; }[]; @@ -119,6 +136,8 @@ export type ReadThreadResult = { readonly backend: ChatGptDesktopBackend; readonly limit: number; readonly full: boolean; + readonly nextCursor?: string | null; + readonly titleTruncated?: boolean; readonly complete?: boolean; readonly warnings?: readonly string[]; readonly title?: string; diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx index 7a5e03a..30fc7ac 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list threads', description: - 'List Desktop threads, then pass nextCursor as cursor until null. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', + 'List Desktop threads, then pass nextCursor as cursor until null. Pages may stop early at the MCP byte budget. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx index a8c356c..9131095 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop read thread', description: - 'Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Recent defaults to 100 turns; full pages up to 2000 from the start. Archived threads remain readable. complete:false means partial history; warnings preserve app-server/frame errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.', + 'Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Pass nextCursor back as cursor with the same threadId/full mode until complete:true. Pages stop at a byte budget; oversized turns use ordered continuation fragments with stable turnKey and field offsets, without dropping text. Archived threads remain readable. Warnings explain partial pages or app-server errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -29,6 +29,7 @@ export default defineTool( 'local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.', }, limit: { type: 'number' }, + cursor: { type: 'string', description: 'Opaque nextCursor from the prior read page. Keep threadId and full unchanged.' }, full: { type: 'boolean', description: diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx index c816c5e..528a895 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop search threads', description: - 'Search Desktop thread metadata by case-insensitive substring. Dynamic hostId/hostName, modelProvider, and project filters apply. Search scans bounded app-server pages and reports warnings if incomplete; use list_threads cursor for exhaustive paging. Remote results identify hostId and cannot be read on this Mac.', + 'Search full Desktop thread metadata by case-insensitive substring. Display titles are capped at 200 characters with titleTruncated:true. Pass nextCursor as cursor with unchanged query and filters to retrieve all matches. Dynamic hostId/hostName, modelProvider, and project filters apply. Remote results identify hostId and cannot be read on this Mac.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, @@ -24,6 +24,7 @@ export default defineTool( port: { type: 'number' }, query: { type: 'string', description: 'Case-insensitive substring over thread metadata.' }, limit: { type: 'number', default: 50, description: 'Maximum matches.' }, + cursor: { type: 'string', description: 'Opaque nextCursor from the previous search page; keep query and filters unchanged.' }, host: { type: 'string', description: diff --git a/src/skills/chatgpt-desktop/SKILL.md b/src/skills/chatgpt-desktop/SKILL.md index 07a024b..5c32b3b 100644 --- a/src/skills/chatgpt-desktop/SKILL.md +++ b/src/skills/chatgpt-desktop/SKILL.md @@ -19,12 +19,18 @@ another machine. host name from a project label. Managed SSH hosts may have no threads. 3. Use `chatgpt_desktop_list_threads` with `host`, `modelProvider`, or `project` as needed. Pass `nextCursor` back as `cursor` with the same filters until it - is `null`. `chatgpt_desktop_search_threads` scans metadata for a substring; - inspect `warnings` if a source failed or the scan was capped. + is `null`. Pages can stop before `limit` to stay under the MCP document cap. + `chatgpt_desktop_search_threads` also accepts `cursor`; keep its query and + filters unchanged. Search matches the full title even when the display row + has a 200-character `title` and `titleTruncated: true`. 4. Read with `chatgpt_desktop_read_thread`. `full: false` gets the recent tail; - `full: true` pages from the start (up to 2,000 turns unless `limit` is set). - Check `complete` and `warnings` before treating it as full history. A turn - may contain both `userText` and `assistantText`. + `full: true` pages chronologically from the start. Pass `nextCursor` back + as `cursor` with the same thread ID and `full` value until `complete: true`. + The byte budget can stop before `limit`. An oversized turn is returned as + ordered fragments with one stable `turnKey`; use `continuation.field`, + `offsetChars`, and `totalChars` to reassemble `text`, `userText`, and + `assistantText`. `textTruncated: true` signals a fragment, not missing text. + Check `complete` and `warnings` before treating a page as full history. Durable local IDs are `local:` (a bare conversation ID also works). `local:client-new-thread:*` is temporary and works only while that diff --git a/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts b/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts index 5c771ce..622ff35 100644 --- a/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts +++ b/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts @@ -5,9 +5,10 @@ import { afterEach, expect, it, rstest } from '@rstest/core'; import { findRemoteThreadHost } from '../../src/core/codex/remote-control.js'; import { listDiscoveredHosts, listRemoteThreadsFromState } from '../../src/core/chatgpt-desktop/remote-threads.js'; import { ChatGptDesktopFacade, finalizeThreadList } from '../../src/core/chatgpt-desktop/facade.js'; -import { appServerReadThread, appServerSearchThreads, discoverModelProviders } from '../../src/core/chatgpt-desktop/app-server-fallback.js'; +import { appServerListThreads, appServerReadThread, appServerSearchThreads, discoverModelProviders } from '../../src/core/chatgpt-desktop/app-server-fallback.js'; +import { DESKTOP_RESULT_BUDGET_BYTES, serializedBytes } from '../../src/core/chatgpt-desktop/payload-budget.js'; import { ARCHIVED_THREAD_EXPRESSION, CONVERSATION_ID_EXPRESSION, LOADING_TASK_GONE_EXPRESSION, navigateToThreadExpression, openThreadInDom, readTurnsFromDom, startNewChatExpression, startNewChatInDom, waitForLoadingTaskGone } from '../../src/core/chatgpt-desktop/cdp-dom.js'; -import { listThreadsOperation, listThreadsSchema, readThreadOperation, readThreadSchema, statusOperation } from '../../src/core/chatgpt-desktop/routes.js'; +import { listThreadsOperation, listThreadsSchema, readThreadOperation, readThreadSchema, searchThreadsSchema, statusOperation } from '../../src/core/chatgpt-desktop/routes.js'; import { setChatGptDesktopAdapterForTests } from '../../src/core/chatgpt-desktop/facade.js'; import type { ChatGptDesktopAdapter } from '../../src/core/chatgpt-desktop/adapter.js'; @@ -63,6 +64,25 @@ it('counts CDP-only remote rows in host discovery', async () => { expect((await facade.listHosts()).hosts).toEqual(expect.arrayContaining([expect.objectContaining({ hostId: 'remote:dynamic', threadCount: 1 })])); }); +it('uses the same deduplicated remote rows for host count and host-filtered list', async () => { + const row = (id: string) => ({ threadId: `local:${id}`, title: id, pinned: false, selected: false, + kind: 'remote', location: 'remote' as const, hostId: 'remote:one', hostName: null }); + const facade = new ChatGptDesktopFacade({ + connect: async () => {}, listThreads: async () => ({ backend: 'cdp', limit: 200, + threads: [row('shared'), row('cdp-only')] }), + } as unknown as ChatGptDesktopAdapter, 9222, { + listThreads: async () => ({ backend: 'app-server', limit: 25, threads: [] }), + listRemoteThreads: () => [row('shared'), row('state-only')], + listHosts: () => [{ hostId: 'remote:one', hostName: 'host'.repeat(2000), location: 'remote', threadCount: 2 }], + discoverModelProviders: async () => ({ providers: [], source: 'thread/list-distinct', threadCount: 0, complete: true }), + } as never); + const hosts = await facade.listHosts(); + const listed = await facade.listThreads({ host: 'remote:one', limit: 100 }); + expect(hosts.hosts.find((host) => host.hostId === 'remote:one')?.threadCount).toBe(listed.threads.length); + expect(hosts.hosts.find((host) => host.hostId === 'remote:one')).toMatchObject({ hostNameTruncated: true }); + expect(listed.threads.map((thread) => thread.threadId).sort()).toEqual(['local:cdp-only', 'local:shared', 'local:state-only']); +}); + it('surfaces provider discovery errors with the remote fallback', async () => { const facade = new ChatGptDesktopFacade({} as ChatGptDesktopAdapter, 9222, { listThreads: async () => ({ backend: 'app-server', limit: 25, threads: [] }), @@ -129,6 +149,90 @@ it('completes a 146-turn full read in bounded pages', async () => { expect(Math.max(...pages)).toBe(10); }); +it('pages a serialized history above the document budget without losing turns', async () => { + const bridge = await import('../../src/core/codex-bridge.js'); + rstest.spyOn(bridge, 'openCodexSession').mockResolvedValue({ client: { + close() {}, + async request(method: string, params: Record) { + if (method === 'thread/read') return { thread: { id: 'huge' } }; + const offset = Number(params.cursor ?? 0); + return { data: Array.from({ length: Math.min(10, 30 - offset) }, (_, i) => ({ + id: `turn-${offset + i}`, items: [{ type: 'agentMessage', text: 'x'.repeat(30_000) }], + })), nextCursor: offset + 10 < 30 ? String(offset + 10) : null }; + }, + } } as never); + const keys: string[] = []; + let cursor: string | undefined; + for (let page = 0; page < 20; page++) { + const out = await appServerReadThread({ threadId: 'huge', full: true, cursor }); + expect(serializedBytes(out)).toBeLessThan(DESKTOP_RESULT_BUDGET_BYTES); + keys.push(...out.turns.map((turn) => turn.turnKey)); + if (out.complete) break; + expect(out.nextCursor).toBeTruthy(); + cursor = out.nextCursor!; + } + expect(keys).toEqual(Array.from({ length: 30 }, (_, i) => `history-content:turn:turn-${i}`)); +}); + +it('splits one oversized turn into lossless ordered field fragments with a stable key', async () => { + const bridge = await import('../../src/core/codex-bridge.js'); + const userText = 'u'.repeat(700_000); + const assistantText = 'a'.repeat(700_000); + rstest.spyOn(bridge, 'openCodexSession').mockResolvedValue({ client: { + close() {}, + async request(method: string) { + if (method === 'thread/read') return { thread: { id: 'giant' } }; + return { data: [{ id: 'giant-turn', items: [ + { type: 'userMessage', text: userText }, { type: 'agentMessage', text: assistantText }, + ] }], nextCursor: null }; + }, + } } as never); + const fields = { text: '', userText: '', assistantText: '' }; + let cursor: string | undefined; + for (let page = 0; page < 100; page++) { + const out = await appServerReadThread({ threadId: 'giant', full: true, cursor }); + expect(serializedBytes(out)).toBeLessThan(DESKTOP_RESULT_BUDGET_BYTES); + for (const turn of out.turns) { + expect(turn.turnKey).toBe('history-content:turn:giant-turn'); + expect(turn.textTruncated).toBe(true); + const field = turn.continuation!.field; + expect(turn.continuation!.offsetChars).toBe(fields[field].length); + fields[field] += turn[field] ?? ''; + } + if (out.complete) break; + cursor = out.nextCursor!; + } + expect(fields).toEqual({ text: assistantText, userText, assistantText }); +}); + +it('compacts oversized list titles across pages and searches the original full title', async () => { + const bridge = await import('../../src/core/codex-bridge.js'); + const title = `${'x'.repeat(7_400)} unique-tail`; + rstest.spyOn(bridge, 'listCodexThreads').mockImplementation(async ({ cursor } = {}) => { + const offset = Number(cursor ?? 0); + return { limit: 25, threads: Array.from({ length: Math.min(25, 60 - offset) }, (_, i) => ({ + id: `id-${offset + i}`, name: title, + })), nextCursor: offset + 25 < 60 ? String(offset + 25) : null } as never; + }); + const ids: string[] = []; + let cursor: string | undefined; + for (let page = 0; page < 10; page++) { + const out = await appServerListThreads({ limit: 100, cursor }); + expect(serializedBytes(out)).toBeLessThan(DESKTOP_RESULT_BUDGET_BYTES); + expect(out.threads.every((row) => row.title.length <= 200 && row.titleTruncated)).toBe(true); + ids.push(...out.threads.map((row) => row.threadId)); + if (!out.nextCursor) break; + cursor = out.nextCursor; + } + expect(ids).toEqual(Array.from({ length: 60 }, (_, i) => `local:id-${i}`)); + const search = await appServerSearchThreads({ query: 'unique-tail', limit: 10 }); + expect(search.threads).toHaveLength(10); + expect(search.threads[0].titleTruncated).toBe(true); + expect((await appServerSearchThreads({ query: 'unique-tail', limit: 10, cursor: search.nextCursor! })).threads[0].threadId).toBe('local:id-10'); + expect(searchThreadsSchema.parse({ query: 'unique-tail', cursor: search.nextCursor }).cursor).toBe(search.nextCursor); + expect(readThreadSchema.parse({ threadId: 'giant', cursor: 'opaque' }).cursor).toBe('opaque'); +}); + it('defaults full reads to the bounded complete-history limit', async () => { const limits: number[] = []; setChatGptDesktopAdapterForTests({ From dc3812366913bd653e459ef48f0e7adf930a4930 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 28 Sep 2026 22:16:50 -0700 Subject: [PATCH 25/26] fix: page merged Desktop inventory and resolve project scope --- .../desktop-merged-pagination-projects.md | 5 + artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 790 +++++++++++------ artifact/bin/gbot.mjs | 792 +++++++++++------ artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 798 +++++++++++------ artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 800 ++++++++++++------ artifact/skills/chatgpt-desktop/SKILL.md | 15 +- docs/chatgpt-desktop-cdp.md | 16 +- .../chatgpt-desktop/app-server-fallback.ts | 54 +- src/core/chatgpt-desktop/cdp-adapter.ts | 14 +- src/core/chatgpt-desktop/cdp-dom.ts | 65 +- src/core/chatgpt-desktop/errors.ts | 23 + src/core/chatgpt-desktop/facade.ts | 231 +++-- src/core/chatgpt-desktop/project-state.ts | 88 ++ src/core/chatgpt-desktop/types.ts | 3 +- .../tools/chatgpt_desktop_list_threads.tsx | 2 +- .../grok-bot/tools/chatgpt_desktop_send.tsx | 2 +- src/skills/chatgpt-desktop/SKILL.md | 15 +- .../chatgpt-desktop-e2e-regressions.test.ts | 165 ++-- .../chatgpt-desktop-mcp-followup.test.ts | 30 +- tests/route-unit/chatgpt-desktop.test.ts | 2 +- 22 files changed, 2737 insertions(+), 1177 deletions(-) create mode 100644 .changeset/desktop-merged-pagination-projects.md create mode 100644 src/core/chatgpt-desktop/project-state.ts diff --git a/.changeset/desktop-merged-pagination-projects.md b/.changeset/desktop-merged-pagination-projects.md new file mode 100644 index 0000000..8667a8d --- /dev/null +++ b/.changeset/desktop-merged-pagination-projects.md @@ -0,0 +1,5 @@ +--- +"grok-bot-cli": patch +--- + +Page ChatGPT Desktop threads from a stable, sorted merged inventory so CDP and remote rows appear once in their timestamp range and requested page sizes are filled. Resolve project labels from Desktop assignments and workspace roots. Verify new-chat navigation and project scope before sending, and report unavailable project roots promptly. diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index f1481be..d6e9baa 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"225ed69f7df9015fb9cd82e62eef99983218c0174b8995b662b6ea6599139486"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"8778d8f3ec854154b04a93c744a730488b7a173286e871da054fe4e4bf891f9b"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"3a966160704621cd614ae9217051b2a681c0c913dd7507020c71c79f02161486"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"9fce685e16123d69e18879ff13f4fea628efc6b58baff3fa21c28455c83ea2ce"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"5321ab3059c80bb27792805e07744c3360890e955842c612e2a95bdf3d866590"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"faf9fe6e3f82f9ae4a7ea61d04c2099c98057e325888e8769aa552b339c046cb"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/facade.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"4aeefdb20d12412c6b2aa60267adc1cab7d9bec983bc14842f24eec4356aba9d"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/chatgpt-desktop/facade.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"8909903b828c9ee383517f3e8c621536fd1ebdf95ece636f2a19fa0101602496"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"3a966160704621cd614ae9217051b2a681c0c913dd7507020c71c79f02161486"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/facade.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"6e2ae3edd0f2fa384effd01206c779b79b4ac1c86aaa336dd68521bfc0cba89c"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/chatgpt-desktop/facade.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"3ec354d5588fe43916dc82f42b035c52c79170a9fbdef43ee330fe7c44664194"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"faf9fe6e3f82f9ae4a7ea61d04c2099c98057e325888e8769aa552b339c046cb"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 199bd94..03de640 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.2"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"25847f479fe3ee1932544d6eb9bbdbef551b556f033bdb61b5ad066f0b7b460a","packageName":"grok-bot-cli","packageVersion":"0.10.2","revision":"b44c00e7af2b9dae6ddf3367221eea576764511f0590cb8336e3c61c0d0c627d","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/desktop-e2e-reliability.md","sha256":"ebb912d56ba3321df13a9d611780129af8f4c264dbc5e841df6c1a8a838dfc10"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"30aaeac24084f0a642d811aa493fc51b0fd3eddff322d359c39c573d8394ff3e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"49d0b5b880153fa7be882f31c8edf73cf04fe0a5f83e2bb880a48ccda495044d"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"153f42cdf9d8e433cb19c2e9842d75333f6afbdf2ce32d48f87829eedcf2247a"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"42509e8e4c2b519949f06d4e7028b8973d56f8fc0cd98decdb231375bb49d38d"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"4894d2ae20d895b1b213c0bd7eb7a6c483a7ae632e49ffeaa4eb7564bc71abde"},{"executable":false,"path":"README.md","sha256":"efe1a601a87648defca4b223f5b6828ead8f17fc15ad1fb8eeac23b9b61b8b29"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"11c86f604c2ee405f7544394db60ee1b36917d0b90769d441fcd361b5f0fe038"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"0dc3acdea178ff14d6c1c4b8b3bf1e18af47984f63b8ed8c41483e4da4b72f08"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"b801a028980e60fe37dca56e86887a1e2b0b8ce80ce77b379e7375d2e4544d5e"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"d0a33935d992af349c52ef448622da5e460b4af1a9474aac60994295245b43ad"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/new.tsx","sha256":"11d0658c1a3e7173d53b71446b184fccccd867baefc6f733e43a9d543ca26ec9"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"a1b30f053a9e65bac561cd04d1361e292e2c672bbf69a6d76d2bdda441c46757"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"0a4cc6c440ad496682031658bda375fee29f5c346d833618d4f143de29b351cd"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/commands/codex-send.md","sha256":"ef29096075a13a28be9c2ee7a6226f169ffd330a7f21698b3927273070a6086d"},{"executable":false,"path":"src/commands/codex-threads.md","sha256":"bacac58bb4e61766ea76f9abad71c25207192bc609ce3bf3f122686c00d674a4"},{"executable":false,"path":"src/commands/codex-wait.md","sha256":"ef224414fe7a9f2aaaae2fba8b83f0600cb3589dfc20920a69b29db3a5f2d880"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5a0a4f2cea9f1fc1a739c534aed3979c28e0bd9c057b8475e6251974ad44ed7a"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"60c6d7bb5ad2ae3aab9b9af86eb7697cbd7eda7dbcf01dba0b88356bd1855f78"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"e8712876dc3dc28e5bd687191400b8f593f0711588e23bd8f378fabc7f7f970a"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"95322209490160d04fc52a4dfa43f2691b4c4720a7121a3f3686c9f7eb4fbbb8"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"2ec693a70f8d004e0c9ae5abb24d49b31d8c49d64dc2b96037cc32e80de3199d"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"c2900c9402cc977b8667269fe23c843162820f78d3925fd56176b868c9d59505"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"591e6968c008cc75827da94b91c0ea15e573640876814e35e2470342dc8bccf9"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/payload-budget.ts","sha256":"89410474315b3769bad58d3ab61999e169410b7d1fdc20819efb4ee9c82fe1ac"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"ed93418ff5d2bb51016783e7b0a458805e709b212974a66be804ddb9f7038033"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"ccf8cde780da6e6e03f11e4dcc0d9d6bc4a6a3fd20d3210e74f0217e3660b7e1"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"75a24433b127d3b5dfee43f4abdef7e33b43e94b55fcab5877ad20fba94c1913"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"78f0fbba7a5053eb78717c5885a9306871f08beaf39da90df1f815a66b1288d9"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"05abb2253480d0793bf5f6b3db17c47e7d154973747074c7c76a79e6f61b7deb"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"52565007799e98c3bff4297287d8e53005e285a95bab9e4e4d0a088bded4fa8e"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"ae29d05e06cdd8e90bcdd723d277af748e16dc676db1e4b938b7cdd36340ed17"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"ff6e8f3158d171911a35b829cd76e1f5fd8319f8143f727a4854448fc09edeec"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"5b80f7dfe7e438811d9f27c1f9038d7631f8c73266d2ec7b1108c1ce9ecbbb47"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"4007e9908e285036786b7b0291dd480d03d51ad03f973fa578444accffa1f416"},{"executable":false,"path":"src/core/relay/state.js","sha256":"c18eda2f956944d0f318910de5239b954090eab81f7c77b4683e326a6d34b2b8"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"c8409ae9679246d8f907f1e0d16ec1c415d6697f2ce048fb64a599734486b9a6"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"86334421686350ea044fb1160c19b6f5889425feb78fd608675feb8137492090"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"302cb90f620e488d48e11dc7fbe5676d711fd6dcebcab0fa6b387e3ba4221c23"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","sha256":"b415d5bd303693649abae96b6b9d2920d29c797f5367ae8fbb2b62b635528e37"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"6adc4318f4b6c90b1d3970046266197348f79757c0d52ffe991d6338eb1fed6c"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"1d50db88cf7d06a74524c8937ed9045eaaf2560f6766d6c411b3bb55575d1d3f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"cf1cb83c76bb46da6245fe447f811ab6f9a2d4b0b94f21d8fbea97ac324714b1"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"681e50ae6c7d3a04a76ad8eadf865ab9d793b5eb3c78f961a42d0902adacc306"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"2786b62ff2a1a4e68229199935ac63c15614a0f0bdbef74b2d06e0c405516272"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_new.tsx","sha256":"556c8d6f5f2b07b20e9daae7aa8008ee3775582a4d034415fc86fecda0c63866"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"5c02dc335a0354850d05e5827f6124d0ddc08b9b654059984887c55e4cd778c9"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"cb08b094860f3a09c937eb8339108015fe0de57d9f6c6886aea2028cd33ef207"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/chatgpt-desktop/SKILL.md","sha256":"3fa1ad5023fbd000b7164e45d749951c7acc16f79933a945823169ae278d2c92"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"55a1afcdea07f325b3528dd0c546ecc4cbfd6069610ecc4f773f049cd597e69c"},{"executable":false,"path":"test/codex-commands.test.js","sha256":"ab15a53a76eb82dc9c51c9fabd0affd2a1037cde27765fef08ecd0012a2e4495"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"789d0245a8d470860f7535c6ef3849313205097f6df517ab9946e47a789f8534"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"fa44f15f46d0cae486c13be3fae09568f17f8581001ec50a61478bec03f4c28c"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a8c06138d895ffaa30476f3a2ddf1ef50ef73a816a665f749f451d01d9cc2551"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts","sha256":"27c7cabcbc6fea9235aff50674ad564b7aa8a087b1a2257db330131253f7b743"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-mcp-followup.test.ts","sha256":"83c8f33a4c5e1243e353163d864e1fdd2cf0e6564ac5ac71366f01efec952398"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"208dfdea18ccc408a279666a521d2f70fdce9bdaf28f86bc5d053f7ad09a7dd2"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"88904d9d13f2449270ab3275aba933019aae6579d75a74621cdf936cd5a1f959"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7c7d971edaa7ef134d0dfba12208f88ec7f69c11dca79ad61d6e6cfae6d34c43"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/commands/codex-send.md","src/commands/codex-threads.md","src/commands/codex-wait.md","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/new.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/new.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"commands/codex-send.md","sourceInputs":["src/commands/codex-send.md"]},{"path":"commands/codex-threads.md","sourceInputs":["src/commands/codex-threads.md"]},{"path":"commands/codex-wait.md","sourceInputs":["src/commands/codex-wait.md"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_new.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_new.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/chatgpt-desktop/SKILL.md","sourceInputs":["src/skills/chatgpt-desktop/SKILL.md"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"a8f5bf1f109d8f88b4195f3baea389e942af2f0ef544ecc22502326bcf3e742e"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"1420b97dfe289c97c24e855ba758439c94fa0e92aa38aae467312fbe341d5d15"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"a3ab79672b9ab74affae23c25ef06ddc926da90d0ff2499e9471c3e4c6ba475f"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":694,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"12321577920803f3d60bf071167f8b7888d94d720d06c5caa38f3b30c8bfda73"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22276,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"bb05fe989f0067d882fe95967dbe4f389da31b4b4943923d8e98172b1f854b9a"},{"bytes":1572175,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"225ed69f7df9015fb9cd82e62eef99983218c0174b8995b662b6ea6599139486"},{"bytes":2442553,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"8778d8f3ec854154b04a93c744a730488b7a173286e871da054fe4e4bf891f9b"},{"bytes":290,"kind":"generated","path":"commands/codex-send.md","sha256":"6d188a21596115f4aa65e39718cede5eff837749c8652a12e2a5b25d8a3e0ef3"},{"bytes":195,"kind":"generated","path":"commands/codex-threads.md","sha256":"0db562fff831ede9dd300552aecc5b29d347c94ebeb3df9f488cb1a87b990cf8"},{"bytes":205,"kind":"generated","path":"commands/codex-wait.md","sha256":"fb04448a474b2f14ddb59739d5f79bcf251a3e1136ffe9b3e50ca5654aa6070b"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"5fdafbf8a3fa3d2205e6a308d37deb8ad31910927334a855f70e11977d43f6a9"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"d5c328ca82057cd05b90372a8cfa8ed3e8c6f7f1b14b1f579ae82250722c3d93"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270116,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"3a966160704621cd614ae9217051b2a681c0c913dd7507020c71c79f02161486"},{"bytes":1502931,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"9fce685e16123d69e18879ff13f4fea628efc6b58baff3fa21c28455c83ea2ce"},{"bytes":3330388,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"5321ab3059c80bb27792805e07744c3360890e955842c612e2a95bdf3d866590"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"862f9ff4c106a5b4c3bb09d498a2f395e3450074c8c79525c3a34aa67179d594"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1305648,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"faf9fe6e3f82f9ae4a7ea61d04c2099c98057e325888e8769aa552b339c046cb"},{"bytes":4168,"kind":"copy","path":"skills/chatgpt-desktop/SKILL.md","sha256":"3fa1ad5023fbd000b7164e45d749951c7acc16f79933a945823169ae278d2c92"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"description":"Opaque nextCursor from the prior read page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Recent default 100; full default 2000","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a prior search page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false},{"description":"Explicitly unarchive an existing archived thread before sending.","key":"unarchive","kind":"boolean","option":"unarchive","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a previous page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"Start a new Codex thread in --cwd, optionally with --model, --effort and a message.","exitCode":"result","options":[{"key":"cwd","kind":"string","option":"cwd","repeated":false,"required":true},{"choices":["none","minimal","low","medium","high","xhigh"],"key":"effort","kind":"enum","option":"effort","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":0,"repeated":true,"required":false},{"key":"model","kind":"string","option":"model","repeated":false,"required":false}],"path":["codex","new"],"routeId":"cli:codex/new"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"choices":["none","minimal","low","medium","high","xhigh"],"key":"effort","kind":"enum","option":"effort","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"model","kind":"string","option":"model","repeated":false,"required":false},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-7200000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-7200000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page","type":"string"},"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a prior search page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/new.tsx#inputJsonSchema","description":"Start a new Codex thread in --cwd, optionally with --model, --effort and a message.","id":"cli:codex/new","inputSchema":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/new.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page","type":"string"},"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a prior search page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/new.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/new.tsx"},"routes":["cli:codex/new"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_open_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page. Keep threadId and full unchanged.","type":"string"},"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the previous search page; keep query and filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_new.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"type":"string"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_new.tsx"},"routes":["tool:grok-bot/codex_new"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"aaaa05be60f4408c4067a950ca63b01c557e1f2a417471d6760bbff44d193a40","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover local, remote-control environment ids, managed SSH hosts, and modelProvider ids. hostName is null when Desktop has no real display name. Use hostId or label in list/search filters; remote thread ids must be read on the owning host. warnings report provider discovery failures.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List Desktop threads, then pass nextCursor as cursor until null. Pages may stop early at the MCP byte budget. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","description":"Navigate Desktop to an existing local: or bare conversation id, even when the row is absent from the sidebar. Archived routes return archived:true without unarchiving; read them with chatgpt_desktop_read_thread. A remote-control id is owned by its hostId and cannot be opened on this Mac. CDP_UNREACHABLE means Desktop must be reachable locally.","id":"tool:grok-bot/chatgpt_desktop_open_thread","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Pass nextCursor back as cursor with the same threadId/full mode until complete:true. Pages stop at a byte budget; oversized turns use ordered continuation fragments with stable turnKey and field offsets, without dropping text. Archived threads remain readable. Warnings explain partial pages or app-server errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page. Keep threadId and full unchanged.","type":"string"},"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search full Desktop thread metadata by case-insensitive substring. Display titles are capped at 200 characters with titleTruncated:true. Pass nextCursor as cursor with unchanged query and filters to retrieve all matches. Dynamic hostId/hostName, modelProvider, and project filters apply. Remote results identify hostId and cannot be read on this Mac.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the previous search page; keep query and filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Check local ChatGPT Desktop CDP before send, wait, or open. reachable:false and exitCode:1 mean CDP is down even if appServerFallback.reachable is true; list/search/read may still work through app-server. There is no remote CDP transport.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"After chatgpt_desktop_send, wait for the selected Desktop reply over CDP. Accept the returned durable local: or the temporary local:client-new-thread:* while selected; omit threadId only when staying on the same selected chat. Returns reply, durable threadId and conversationId. timeout is not proof the send failed; CDP_UNREACHABLE requires Desktop recovery. Remote ids must be handled on their hostId.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_new.tsx#inputJsonSchema","description":"Start a new Codex thread on this machine in cwd, optionally sending its first message. Codex must run locally on the same machine as gbot.","id":"tool:grok-bot/codex_new","inputSchema":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"type":"string"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_new.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.2"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"b462f5594e8174bb3c565276aa2dcb5f56094d68add7f8b991b09701ed1417a6","packageName":"grok-bot-cli","packageVersion":"0.10.2","revision":"d3cb1cb2af48ebb834a56a0a61122995eaf17be181702494890027c6a529784a","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/desktop-e2e-reliability.md","sha256":"ebb912d56ba3321df13a9d611780129af8f4c264dbc5e841df6c1a8a838dfc10"},{"executable":false,"path":".changeset/desktop-merged-pagination-projects.md","sha256":"686b95a887f227380fce54a4a36c227b8a53b924038ddaad82d1c2a778699168"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"30aaeac24084f0a642d811aa493fc51b0fd3eddff322d359c39c573d8394ff3e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"49d0b5b880153fa7be882f31c8edf73cf04fe0a5f83e2bb880a48ccda495044d"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"6dd6cfe00e9a888c1ced79f1db85744f9c92affef8a78126e22ea5205e76b732"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"42509e8e4c2b519949f06d4e7028b8973d56f8fc0cd98decdb231375bb49d38d"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"4894d2ae20d895b1b213c0bd7eb7a6c483a7ae632e49ffeaa4eb7564bc71abde"},{"executable":false,"path":"README.md","sha256":"efe1a601a87648defca4b223f5b6828ead8f17fc15ad1fb8eeac23b9b61b8b29"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"11c86f604c2ee405f7544394db60ee1b36917d0b90769d441fcd361b5f0fe038"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"0dc3acdea178ff14d6c1c4b8b3bf1e18af47984f63b8ed8c41483e4da4b72f08"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"b801a028980e60fe37dca56e86887a1e2b0b8ce80ce77b379e7375d2e4544d5e"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"d0a33935d992af349c52ef448622da5e460b4af1a9474aac60994295245b43ad"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/new.tsx","sha256":"11d0658c1a3e7173d53b71446b184fccccd867baefc6f733e43a9d543ca26ec9"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"a1b30f053a9e65bac561cd04d1361e292e2c672bbf69a6d76d2bdda441c46757"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"0a4cc6c440ad496682031658bda375fee29f5c346d833618d4f143de29b351cd"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/commands/codex-send.md","sha256":"ef29096075a13a28be9c2ee7a6226f169ffd330a7f21698b3927273070a6086d"},{"executable":false,"path":"src/commands/codex-threads.md","sha256":"bacac58bb4e61766ea76f9abad71c25207192bc609ce3bf3f122686c00d674a4"},{"executable":false,"path":"src/commands/codex-wait.md","sha256":"ef224414fe7a9f2aaaae2fba8b83f0600cb3589dfc20920a69b29db3a5f2d880"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5a0a4f2cea9f1fc1a739c534aed3979c28e0bd9c057b8475e6251974ad44ed7a"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"405ba6ccf579016440f3528d3786f52a8e2fbb15f10a70da4cdf374b84db3fee"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"db60fdd3be0259a6c76cad7d8ff86eddc6acbbd21c5f20d6aeffff5390063efa"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"a122fb76626006fa8dedb7088f9b5533a8058c3a58838692b168e0753b7c89eb"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"941ce4a9148fc53086cce64336dba473c1f7e4138774fd50a8ae524dcc05d34d"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"992aa3f5196f00d2c2267383d2eb00d18b2b39e503f41255da1d7911d58574ee"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"591e6968c008cc75827da94b91c0ea15e573640876814e35e2470342dc8bccf9"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/payload-budget.ts","sha256":"89410474315b3769bad58d3ab61999e169410b7d1fdc20819efb4ee9c82fe1ac"},{"executable":false,"path":"src/core/chatgpt-desktop/project-state.ts","sha256":"b33e55b6d6abf15f3d7d1489b8b178d4e907ea83ed1a47d88f8f178a574709f8"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"ed93418ff5d2bb51016783e7b0a458805e709b212974a66be804ddb9f7038033"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"ccf8cde780da6e6e03f11e4dcc0d9d6bc4a6a3fd20d3210e74f0217e3660b7e1"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"59f89694eed34206e32db2a0afb48670bb164a4ffffacb907c8629bb0ce4bcca"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"78f0fbba7a5053eb78717c5885a9306871f08beaf39da90df1f815a66b1288d9"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"05abb2253480d0793bf5f6b3db17c47e7d154973747074c7c76a79e6f61b7deb"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"52565007799e98c3bff4297287d8e53005e285a95bab9e4e4d0a088bded4fa8e"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"ae29d05e06cdd8e90bcdd723d277af748e16dc676db1e4b938b7cdd36340ed17"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"ff6e8f3158d171911a35b829cd76e1f5fd8319f8143f727a4854448fc09edeec"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"5b80f7dfe7e438811d9f27c1f9038d7631f8c73266d2ec7b1108c1ce9ecbbb47"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"4007e9908e285036786b7b0291dd480d03d51ad03f973fa578444accffa1f416"},{"executable":false,"path":"src/core/relay/state.js","sha256":"c18eda2f956944d0f318910de5239b954090eab81f7c77b4683e326a6d34b2b8"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"c8409ae9679246d8f907f1e0d16ec1c415d6697f2ce048fb64a599734486b9a6"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"86334421686350ea044fb1160c19b6f5889425feb78fd608675feb8137492090"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"5f24cfdace92522891dfbaed0bd90e74b7de6bb8d193e0ef3bd5582c05a06914"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","sha256":"b415d5bd303693649abae96b6b9d2920d29c797f5367ae8fbb2b62b635528e37"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"6adc4318f4b6c90b1d3970046266197348f79757c0d52ffe991d6338eb1fed6c"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"1d50db88cf7d06a74524c8937ed9045eaaf2560f6766d6c411b3bb55575d1d3f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"9e1b93735b9a38216c7e9aac4c5b62bc2ac20b60e1979a19c4610f0208961af5"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"681e50ae6c7d3a04a76ad8eadf865ab9d793b5eb3c78f961a42d0902adacc306"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"2786b62ff2a1a4e68229199935ac63c15614a0f0bdbef74b2d06e0c405516272"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_new.tsx","sha256":"556c8d6f5f2b07b20e9daae7aa8008ee3775582a4d034415fc86fecda0c63866"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"5c02dc335a0354850d05e5827f6124d0ddc08b9b654059984887c55e4cd778c9"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"cb08b094860f3a09c937eb8339108015fe0de57d9f6c6886aea2028cd33ef207"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/chatgpt-desktop/SKILL.md","sha256":"0fe2560037f761203a317bf8755b0476ce864b7b1b13708559448d300aa4635c"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"55a1afcdea07f325b3528dd0c546ecc4cbfd6069610ecc4f773f049cd597e69c"},{"executable":false,"path":"test/codex-commands.test.js","sha256":"ab15a53a76eb82dc9c51c9fabd0affd2a1037cde27765fef08ecd0012a2e4495"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"789d0245a8d470860f7535c6ef3849313205097f6df517ab9946e47a789f8534"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"fa44f15f46d0cae486c13be3fae09568f17f8581001ec50a61478bec03f4c28c"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a8c06138d895ffaa30476f3a2ddf1ef50ef73a816a665f749f451d01d9cc2551"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts","sha256":"b1a5818fc873c318e9978c92dd75b97f995fa6871a88cef6d90ab6e8d439e39e"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-mcp-followup.test.ts","sha256":"4a2db11a642b8daef05285f096ce026ca5b9b6394c31c0966d7e5f8c1d49f4ca"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"208dfdea18ccc408a279666a521d2f70fdce9bdaf28f86bc5d053f7ad09a7dd2"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"5cf61e174b1d4a7c0f2209d6746bb1880a96fe550f7d2c4ea94e849dd7f21299"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7c7d971edaa7ef134d0dfba12208f88ec7f69c11dca79ad61d6e6cfae6d34c43"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/commands/codex-send.md","src/commands/codex-threads.md","src/commands/codex-wait.md","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/new.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/project-state.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/new.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/project-state.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"commands/codex-send.md","sourceInputs":["src/commands/codex-send.md"]},{"path":"commands/codex-threads.md","sourceInputs":["src/commands/codex-threads.md"]},{"path":"commands/codex-wait.md","sourceInputs":["src/commands/codex-wait.md"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/project-state.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_new.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/project-state.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_new.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/chatgpt-desktop/SKILL.md","sourceInputs":["src/skills/chatgpt-desktop/SKILL.md"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"a8f5bf1f109d8f88b4195f3baea389e942af2f0ef544ecc22502326bcf3e742e"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"1420b97dfe289c97c24e855ba758439c94fa0e92aa38aae467312fbe341d5d15"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"a3ab79672b9ab74affae23c25ef06ddc926da90d0ff2499e9471c3e4c6ba475f"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":694,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"12321577920803f3d60bf071167f8b7888d94d720d06c5caa38f3b30c8bfda73"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22592,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"7ed7f3f8f44939f00966c0ee2f89a2a8c95bdf3b63bea7d976a1a9414df034d8"},{"bytes":1588943,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"4aeefdb20d12412c6b2aa60267adc1cab7d9bec983bc14842f24eec4356aba9d"},{"bytes":2459321,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"8909903b828c9ee383517f3e8c621536fd1ebdf95ece636f2a19fa0101602496"},{"bytes":290,"kind":"generated","path":"commands/codex-send.md","sha256":"6d188a21596115f4aa65e39718cede5eff837749c8652a12e2a5b25d8a3e0ef3"},{"bytes":195,"kind":"generated","path":"commands/codex-threads.md","sha256":"0db562fff831ede9dd300552aecc5b29d347c94ebeb3df9f488cb1a87b990cf8"},{"bytes":205,"kind":"generated","path":"commands/codex-wait.md","sha256":"fb04448a474b2f14ddb59739d5f79bcf251a3e1136ffe9b3e50ca5654aa6070b"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"5fdafbf8a3fa3d2205e6a308d37deb8ad31910927334a855f70e11977d43f6a9"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"d5c328ca82057cd05b90372a8cfa8ed3e8c6f7f1b14b1f579ae82250722c3d93"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270116,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"3a966160704621cd614ae9217051b2a681c0c913dd7507020c71c79f02161486"},{"bytes":1520465,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"6e2ae3edd0f2fa384effd01206c779b79b4ac1c86aaa336dd68521bfc0cba89c"},{"bytes":3347922,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"3ec354d5588fe43916dc82f42b035c52c79170a9fbdef43ee330fe7c44664194"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"862f9ff4c106a5b4c3bb09d498a2f395e3450074c8c79525c3a34aa67179d594"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1305648,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"faf9fe6e3f82f9ae4a7ea61d04c2099c98057e325888e8769aa552b339c046cb"},{"bytes":4856,"kind":"copy","path":"skills/chatgpt-desktop/SKILL.md","sha256":"0fe2560037f761203a317bf8755b0476ce864b7b1b13708559448d300aa4635c"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"description":"Opaque nextCursor from the prior read page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Recent default 100; full default 2000","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a prior search page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false},{"description":"Explicitly unarchive an existing archived thread before sending.","key":"unarchive","kind":"boolean","option":"unarchive","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a previous page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"Start a new Codex thread in --cwd, optionally with --model, --effort and a message.","exitCode":"result","options":[{"key":"cwd","kind":"string","option":"cwd","repeated":false,"required":true},{"choices":["none","minimal","low","medium","high","xhigh"],"key":"effort","kind":"enum","option":"effort","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":0,"repeated":true,"required":false},{"key":"model","kind":"string","option":"model","repeated":false,"required":false}],"path":["codex","new"],"routeId":"cli:codex/new"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"choices":["none","minimal","low","medium","high","xhigh"],"key":"effort","kind":"enum","option":"effort","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"model","kind":"string","option":"model","repeated":false,"required":false},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-7200000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-7200000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page","type":"string"},"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a prior search page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/new.tsx#inputJsonSchema","description":"Start a new Codex thread in --cwd, optionally with --model, --effort and a message.","id":"cli:codex/new","inputSchema":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/new.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page","type":"string"},"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a prior search page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/new.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/new.tsx"},"routes":["cli:codex/new"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_open_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page. Keep threadId and full unchanged.","type":"string"},"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the previous search page; keep query and filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_new.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"type":"string"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_new.tsx"},"routes":["tool:grok-bot/codex_new"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"c0f041a6aedf5b5e8760c0125a69225707c642edb094259fa080c580fe89668c","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover local, remote-control environment ids, managed SSH hosts, and modelProvider ids. hostName is null when Desktop has no real display name. Use hostId or label in list/search filters; remote thread ids must be read on the owning host. warnings report provider discovery failures.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List one sorted Desktop inventory without duplicate rows. Pass nextCursor as cursor with unchanged filters until null; pages fill limit unless the MCP byte budget binds. A changed/expired inventory cursor requires restarting. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or Desktop project label/projectId; projectRootPath identifies the resolved workspace. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","description":"Navigate Desktop to an existing local: or bare conversation id, even when the row is absent from the sidebar. Archived routes return archived:true without unarchiving; read them with chatgpt_desktop_read_thread. A remote-control id is owned by its hostId and cannot be opened on this Mac. CDP_UNREACHABLE means Desktop must be reachable locally.","id":"tool:grok-bot/chatgpt_desktop_open_thread","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Pass nextCursor back as cursor with the same threadId/full mode until complete:true. Pages stop at a byte budget; oversized turns use ordered continuation fragments with stable turnKey and field offsets, without dropping text. Archived threads remain readable. Warnings explain partial pages or app-server errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page. Keep threadId and full unchanged.","type":"string"},"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search full Desktop thread metadata by case-insensitive substring. Display titles are capped at 200 characters with titleTruncated:true. Pass nextCursor as cursor with unchanged query and filters to retrieve all matches. Dynamic hostId/hostName, modelProvider, and project filters apply. Remote results identify hostId and cannot be read on this Mac.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the previous search page; keep query and filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. The empty view and project scope are checked before typing. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. PROJECT_UNAVAILABLE identifies a disabled project action or missing configured root; NEW_CHAT_NAVIGATION_FAILED reports an unchanged view promptly. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Check local ChatGPT Desktop CDP before send, wait, or open. reachable:false and exitCode:1 mean CDP is down even if appServerFallback.reachable is true; list/search/read may still work through app-server. There is no remote CDP transport.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"After chatgpt_desktop_send, wait for the selected Desktop reply over CDP. Accept the returned durable local: or the temporary local:client-new-thread:* while selected; omit threadId only when staying on the same selected chat. Returns reply, durable threadId and conversationId. timeout is not proof the send failed; CDP_UNREACHABLE requires Desktop recovery. Remote ids must be handled on their hostId.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_new.tsx#inputJsonSchema","description":"Start a new Codex thread on this machine in cwd, optionally sending its first message. Codex must run locally on the same machine as gbot.","id":"tool:grok-bot/codex_new","inputSchema":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"type":"string"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_new.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index e34aa05..72d9fac 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -11419,69 +11419,96 @@ var __webpack_modules__ = { let fetchLimit = Math.min(limit, 25); if (cursor?.startsWith(LIST_PAGE_PREFIX)) { const state = (0, _payload_budget_js__rspack_import_4.i3)(LIST_PAGE_PREFIX, cursor); - if (!Number.isSafeInteger(state.skip) || state.skip < 1 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || state.cursor !== null && typeof state.cursor !== 'string') { + if (!Number.isSafeInteger(state.skip) || state.skip < 0 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || state.cursor !== null && typeof state.cursor !== 'string') { throw new Error('Invalid ChatGPT Desktop list page cursor'); } sourceCursor = state.cursor ?? undefined; skip = state.skip; fetchLimit = state.fetchLimit; } - const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit: fetchLimit, - cursor: sourceCursor, - modelProviders - }); - if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); const base = { backend: 'app-server', limit, modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; const threads = []; - let consumed = skip; - for (const raw of out.threads.slice(skip)){ - if (threads.length >= limit) break; - let row = (0, _payload_budget_js__rspack_import_4.eX)(mapListedThread(raw)); - const probe = { - ...base, - threads: [ - ...threads, - row - ], - nextCursor: LIST_PAGE_PREFIX, - exitCode: 0 - }; - if ((0, _payload_budget_js__rspack_import_4.sQ)(probe) > 614400) { - if (threads.length) break; - row = (0, _payload_budget_js__rspack_import_4.MH)(row); - if ((0, _payload_budget_js__rspack_import_4.sQ)({ + const seen = new Set(); + for(let page = 0; page < 400; page++){ + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit: fetchLimit, + cursor: sourceCursor, + modelProviders + }); + if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); + for(let index = skip; index < out.threads.length; index++){ + let row = (0, _payload_budget_js__rspack_import_4.eX)(mapListedThread(out.threads[index])); + const probe = { ...base, threads: [ + ...threads, row ], nextCursor: LIST_PAGE_PREFIX, exitCode: 0 - }) > 614400) { - throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + }; + if ((0, _payload_budget_js__rspack_import_4.sQ)(probe) > 614400) { + if (threads.length) return { + ...base, + threads, + nextCursor: (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { + cursor: sourceCursor ?? null, + skip: index, + fetchLimit + }), + warnings: [ + 'List page stopped at the MCP byte budget; continue with nextCursor' + ] + }; + row = (0, _payload_budget_js__rspack_import_4.MH)(row); + if ((0, _payload_budget_js__rspack_import_4.sQ)({ + ...base, + threads: [ + row + ], + nextCursor: LIST_PAGE_PREFIX, + exitCode: 0 + }) > 614400) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + threads.push(row); + if (threads.length >= limit) { + const nextCursor = index + 1 < out.threads.length ? (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { + cursor: sourceCursor ?? null, + skip: index + 1, + fetchLimit + }) : out.nextCursor ?? null; + return { + ...base, + threads, + nextCursor + }; } } - threads.push(row); - consumed++; + if (out.nextCursor == null) return { + ...base, + threads, + nextCursor: null + }; + if (typeof out.nextCursor !== 'string' || !out.nextCursor || seen.has(out.nextCursor)) { + throw new Error('ChatGPT Desktop list returned an invalid or repeated cursor'); + } + seen.add(out.nextCursor); + sourceCursor = out.nextCursor; + skip = 0; } - const nextCursor = consumed < out.threads.length ? (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { - cursor: sourceCursor ?? null, - skip: consumed, - fetchLimit - }) : out.nextCursor ?? null; return { ...base, threads, - nextCursor, - ...consumed < out.threads.length ? { - warnings: [ - 'List page stopped at the MCP byte budget; continue with nextCursor' - ] - } : {} + nextCursor: sourceCursor, + warnings: [ + 'List stopped after 400 app-server pages; continue with nextCursor' + ] }; } async function appServerSearchThreads({ query, limit = 50, cursor, modelProviders = [], project }) { @@ -12080,13 +12107,15 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); - var _cdp_session_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); - var _cdp_dom_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); - var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); - var _loopback_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _cdp_session_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); + var _cdp_dom_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); + var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _loopback_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _project_state_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/project-state.ts"); class CdpChatGptDesktopAdapter { - #port = (0, _loopback_js__rspack_import_4.L0)(); + #port = (0, _loopback_js__rspack_import_5.L0)(); #session = null; #version = null; #pageSessionId = null; @@ -12094,8 +12123,8 @@ var __webpack_modules__ = { #submittedTurn = null; async connect({ port }) { await this.close(); - this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); - const session = new _cdp_session_js__rspack_import_1.a(this.#port); + this.#port = (0, _loopback_js__rspack_import_5.L0)(process.env, port); + const session = new _cdp_session_js__rspack_import_2.a(this.#port); try { this.#version = await session.connect(); this.#session = session; @@ -12109,11 +12138,11 @@ var __webpack_modules__ = { async listTargets() { const session = this.#requireSession(); const result = await session.send('Target.getTargets'); - return (0, _cdp_dom_js__rspack_import_2.Mr)(result.targetInfos ?? []); + return (0, _cdp_dom_js__rspack_import_3.Mr)(result.targetInfos ?? []); } async listThreads({ limit = 50 } = {}) { const sessionId = await this.#ensurePageSession(); - const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + const threads = await (0, _cdp_dom_js__rspack_import_3.AY)(this.#requireSession(), sessionId, { limit }); return { @@ -12125,7 +12154,7 @@ var __webpack_modules__ = { async readThread({ threadId, limit = 100, full = false, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); await this.#openAndWait(sessionId, threadId, openTimeoutMs); - const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + const turns = await (0, _cdp_dom_js__rspack_import_3.JU)(this.#requireSession(), sessionId, { limit, full, threadId @@ -12146,26 +12175,27 @@ var __webpack_modules__ = { if (threadId) { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } else { - await (0, _cdp_dom_js__rspack_import_2.s0)(this.#requireSession(), sessionId, { - project - }); - await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { - timeoutMs: openTimeoutMs, - threadId: 'new' + const localProject = project ? (0, _project_state_js__rspack_import_6.q)(project) : null; + if (localProject && !localProject.rootPaths.some((path)=>(0, node_fs__rspack_import_0.existsSync)(path))) { + throw new _errors_js__rspack_import_1.Kn(localProject.label, `none of its configured workspace roots exists: ${localProject.rootPaths.map((path)=>JSON.stringify(path)).join(', ') || '(none)'}. Update the Desktop project root before sending.`); + } + await (0, _cdp_dom_js__rspack_import_3.s0)(this.#requireSession(), sessionId, { + project: localProject?.label ?? project, + projectId: localProject?.id }); - const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + const threads = await (0, _cdp_dom_js__rspack_import_3.AY)(this.#requireSession(), sessionId, { limit: 20 }); - const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); + const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_3.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_3.hA)); if (temp) temporaryThreadId = temp.threadId; } - const before = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); - const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + const before = await (0, _cdp_dom_js__rspack_import_3.YX)(this.#requireSession(), sessionId); + const { sentVia } = await (0, _cdp_dom_js__rspack_import_3.lh)(this.#requireSession(), sessionId, text); let conversationId; - if (startedNew || threadId && (0, _thread_ids_js__rspack_import_3.vr)(threadId)) { + if (startedNew || threadId && (0, _thread_ids_js__rspack_import_4.vr)(threadId)) { const resolveMs = Math.min(openTimeoutMs, 60000); try { - conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { + conversationId = await (0, _cdp_dom_js__rspack_import_3.z9)(this.#requireSession(), sessionId, { timeoutMs: resolveMs }); } catch (error) { @@ -12175,7 +12205,7 @@ var __webpack_modules__ = { }); } } - const durable = (0, _cdp_dom_js__rspack_import_2.X8)(conversationId, threadId); + const durable = (0, _cdp_dom_js__rspack_import_3.X8)(conversationId, threadId); if (!durable) { throw new Error('ChatGPT Desktop send accepted but no durable conversation id was available; ' + 'refusing to return a local:client-new-thread:* id as threadId'); } @@ -12186,7 +12216,7 @@ var __webpack_modules__ = { return { threadId: durable, temporaryThreadId, - conversationId: conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, + conversationId: conversationId || (0, _thread_ids_js__rspack_import_4.nn)(durable) || durable, project, backend: 'cdp', experimental: false, @@ -12198,30 +12228,30 @@ var __webpack_modules__ = { async waitForReply({ threadId, timeoutMs = 120000 }) { const deadline = Date.now() + timeoutMs; const sessionId = await this.#ensurePageSession(); - const expectedId = threadId && threadId !== 'new' ? (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? undefined : this.#submittedTurn ? (0, _thread_ids_js__rspack_import_3.nn)(this.#submittedTurn.threadId) ?? undefined : undefined; - if (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) && threadId !== 'new') { + const expectedId = threadId && threadId !== 'new' ? (0, _thread_ids_js__rspack_import_4.nn)(threadId) ?? undefined : this.#submittedTurn ? (0, _thread_ids_js__rspack_import_4.nn)(this.#submittedTurn.threadId) ?? undefined : undefined; + if (threadId && !(0, _thread_ids_js__rspack_import_4.vr)(threadId) && threadId !== 'new') { await this.#openAndWait(sessionId, threadId, Math.min(timeoutMs, 90000)); } try { - const done = await (0, _cdp_dom_js__rspack_import_2.FG)(this.#requireSession(), sessionId, { + const done = await (0, _cdp_dom_js__rspack_import_3.FG)(this.#requireSession(), sessionId, { timeoutMs: Math.max(0, deadline - Date.now()), expectedConversationId: expectedId, - baselineTurnKey: this.#submittedTurn && (!threadId || (0, _thread_ids_js__rspack_import_3.BS)(threadId) === this.#submittedTurn.threadId) ? this.#submittedTurn.turnKey : undefined + baselineTurnKey: this.#submittedTurn && (!threadId || (0, _thread_ids_js__rspack_import_4.BS)(threadId) === this.#submittedTurn.threadId) ? this.#submittedTurn.turnKey : undefined }); - const durable = (0, _cdp_dom_js__rspack_import_2.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_3.BS)(done.conversationId) : null); + const durable = (0, _cdp_dom_js__rspack_import_3.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_4.BS)(done.conversationId) : null); if (!durable) { throw new Error('ChatGPT Desktop reply finished without a durable conversation id on ' + '[data-response-annotation-conversation]'); } return { threadId: durable, - conversationId: done.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, + conversationId: done.conversationId || (0, _thread_ids_js__rspack_import_4.nn)(durable) || durable, reply: done.reply, backend: 'cdp', experimental: false, delivery: 'replied' }; } catch (error) { - if (!(error instanceof _cdp_dom_js__rspack_import_2.aw)) throw error; + if (!(error instanceof _cdp_dom_js__rspack_import_3.aw)) throw error; return { threadId: threadId ?? 'unknown', reply: '', @@ -12236,7 +12266,7 @@ var __webpack_modules__ = { try { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } catch (error) { - if (error instanceof _errors_js__rspack_import_0.fw) return { + if (error instanceof _errors_js__rspack_import_1.fw) return { threadId, backend: 'cdp', archived: true @@ -12250,15 +12280,15 @@ var __webpack_modules__ = { } async status() { try { - const version = this.#version ?? await _cdp_session_js__rspack_import_1.a.fetchVersion(this.#port); + const version = this.#version ?? await _cdp_session_js__rspack_import_2.a.fetchVersion(this.#port); let targetCount; let mainWindowTargetId; if (this.#session && !this.#session.closed) { const targets = await this.listTargets(); targetCount = targets.length; - mainWindowTargetId = (0, _cdp_dom_js__rspack_import_2.C2)(targets)?.targetId ?? null; + mainWindowTargetId = (0, _cdp_dom_js__rspack_import_3.C2)(targets)?.targetId ?? null; } else { - const list = await _cdp_session_js__rspack_import_1.a.fetchJsonList(this.#port); + const list = await _cdp_session_js__rspack_import_2.a.fetchJsonList(this.#port); targetCount = list.length; } return { @@ -12291,17 +12321,17 @@ var __webpack_modules__ = { this.#session = null; } async #openAndWait(sessionId, threadId, openTimeoutMs) { - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { + await (0, _cdp_dom_js__rspack_import_3.Kl)(this.#requireSession(), sessionId, threadId); + await (0, _cdp_dom_js__rspack_import_3.Zx)(this.#requireSession(), sessionId, { timeoutMs: openTimeoutMs, threadId }); } async #attachMainWindow() { const targets = await this.listTargets(); - const main = (0, _cdp_dom_js__rspack_import_2.C2)(targets); + const main = (0, _cdp_dom_js__rspack_import_3.C2)(targets); if (!main) { - throw new _errors_js__rspack_import_0.sO(`No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`); + throw new _errors_js__rspack_import_1.sO(`No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`); } const attached = await this.#requireSession().send('Target.attachToTarget', { targetId: main.targetId, @@ -12314,13 +12344,13 @@ var __webpack_modules__ = { this.#requireSession(); if (!this.#pageSessionId) await this.#attachMainWindow(); if (!this.#pageSessionId) { - throw new _errors_js__rspack_import_0.sO('Failed to attach to ChatGPT Desktop main window'); + throw new _errors_js__rspack_import_1.sO('Failed to attach to ChatGPT Desktop main window'); } return this.#pageSessionId; } #requireSession() { if (!this.#session || this.#session.closed) { - throw new _errors_js__rspack_import_0.sO('Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.'); + throw new _errors_js__rspack_import_1.sO('Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.'); } return this.#session; } @@ -12511,17 +12541,18 @@ var __webpack_modules__ = { return { ok: false, error: 'router-not-found' }; })()`; } - function startNewChatExpression(project) { + function startNewChatExpression(project, projectId) { const projectSel = project ? newChatInProjectSelector(project) : null; return `(() => { const projectSel = ${JSON.stringify(projectSel)}; if (projectSel) { - const preferred = document.querySelector(projectSel); + const preferred = ${projectId ? `document.querySelector('[data-app-action-sidebar-project-id=${JSON.stringify(projectId)}]')?.querySelector(projectSel) ||` : ''} document.querySelector(projectSel); if (preferred) { - const row = preferred.closest('.group') || preferred.parentElement; + const row = preferred.closest('[data-app-action-sidebar-project-row]') || preferred.parentElement; row?.scrollIntoView({ block: 'center' }); const rowBox = row?.getBoundingClientRect(); return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)}, + disabled: preferred.disabled || preferred.getAttribute('aria-disabled') === 'true', hoverX: rowBox?.left + rowBox?.width / 2, hoverY: rowBox?.top + rowBox?.height / 2 }; } return { ok: false, error: 'project-not-found' }; @@ -12533,15 +12564,40 @@ var __webpack_modules__ = { return { ok: true, via: 'fallback' }; })()`; } - function projectButtonBoxExpression(project) { + function projectButtonBoxExpression(project, projectId) { return `(() => { - const button = document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); + const button = ${projectId ? `document.querySelector('[data-app-action-sidebar-project-id=${JSON.stringify(projectId)}]')?.querySelector(${JSON.stringify(newChatInProjectSelector(project))}) ||` : ''} document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); if (!button) return null; const box = button.getBoundingClientRect(); return { x: box.left + box.width / 2, y: box.top + box.height / 2, - visible: box.width > 0 && box.height > 0 && getComputedStyle(button.parentElement).opacity !== '0' }; + disabled: button.disabled || button.getAttribute('aria-disabled') === 'true', + visible: box.width > 0 && box.height > 0 && box.x >= 0 && box.y >= 0 + && box.x < innerWidth && box.y < innerHeight && getComputedStyle(button.parentElement).opacity !== '0' }; })()`; } + function newChatViewExpression(project) { + return `(() => { + const root = window.__codexRoot?._internalRoot?.current; + const queue = [root]; let scanned = 0; let path = ''; + while (queue.length && scanned++ < 10000) { + const fiber = queue.shift(); if (!fiber) continue; + const router = fiber.memoizedProps?.router; + if (router?.navigate && router?.state?.location) { path = router.state.location.pathname; break; } + if (fiber.child) queue.push(fiber.child); + if (fiber.sibling) queue.push(fiber.sibling); + } + const composer = !!document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + const scope = document.querySelector('[data-composer-navigation-target="workspace-project"]')?.getAttribute('aria-label') || ''; + const expected = ${JSON.stringify(project ? `Change project: ${project}` : '')}; + return { ready: path === '/' && composer && (expected ? scope === expected : (!scope || scope === 'Choose project')), path, composer, scope }; + })()`; + } + const CLEAR_NEW_CHAT_PROJECT_EXPRESSION = `(() => { + const button = document.querySelector('[data-clear-project-button="true"]'); + if (!button || button.disabled) return false; + button.click(); + return true; +})()`; const LOADING_TASK_GONE_EXPRESSION = `(() => { const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); @@ -12727,14 +12783,15 @@ var __webpack_modules__ = { } throw new Error(loadingGone ? `ChatGPT Desktop timed out waiting for conversation ${JSON.stringify(threadId)}; displayed conversation ${JSON.stringify(lastConversationId)} after ${timeoutMs}ms` : `ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); } - async function startNewChatInDom(session, sessionId, { project } = {}) { - const result = await session.evaluate(startNewChatExpression(project), { + async function startNewChatInDom(session, sessionId, { project, projectId, navigationTimeoutMs = 3000 } = {}) { + const result = await session.evaluate(startNewChatExpression(project, projectId), { sessionId }); if (!result?.ok) { throw new Error(project ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` : 'ChatGPT Desktop "New chat" button not found'); } if (result.via === 'project') { + if (result.disabled) throw new _errors_js__rspack_import_0.Kn(project, 'the Desktop project new-chat action is disabled; check its configured workspace root'); if (![ result.hoverX, result.hoverY @@ -12748,9 +12805,10 @@ var __webpack_modules__ = { }, { sessionId }); - const button = await session.evaluate(projectButtonBoxExpression(project), { + const button = await session.evaluate(projectButtonBoxExpression(project, projectId), { sessionId }); + if (button?.disabled) throw new _errors_js__rspack_import_0.Kn(project, 'the Desktop project new-chat action is disabled; check its configured workspace root'); if (!button?.visible || !Number.isFinite(button.x) || !Number.isFinite(button.y)) { throw new Error(`ChatGPT Desktop project button did not appear after hover for ${JSON.stringify(project)}`); } @@ -12780,9 +12838,28 @@ var __webpack_modules__ = { sessionId }); } - return { - via: result.via ?? 'unknown' + let observed = { + ready: false, + path: '', + composer: false, + scope: '' }; + const deadline = Date.now() + navigationTimeoutMs; + while(Date.now() < deadline){ + observed = await session.evaluate(newChatViewExpression(project), { + sessionId + }); + if (observed?.ready) return { + via: result.via ?? 'unknown' + }; + if (!project && observed?.path === '/' && observed?.composer && observed.scope.startsWith('Change project: ')) { + await session.evaluate(CLEAR_NEW_CHAT_PROJECT_EXPRESSION, { + sessionId + }); + } + await delay(100); + } + throw new _errors_js__rspack_import_0.XL(project, `route ${JSON.stringify(observed?.path)}, composer ${Boolean(observed?.composer)}, project ${JSON.stringify(observed?.scope)}`); } async function focusComposer(session, sessionId) { const focused = await session.evaluate(FOCUS_COMPOSER_EXPRESSION, { @@ -13207,6 +13284,24 @@ var __webpack_modules__ = { this.name = 'ComposerDraftError'; } } + class ProjectUnavailableError extends Error { + code = 'PROJECT_UNAVAILABLE'; + reason = 'project-unavailable'; + delivery = 'rejected'; + constructor(project, detail){ + super(`ChatGPT Desktop cannot start a chat in project ${JSON.stringify(project)}: ${detail}`); + this.name = 'ProjectUnavailableError'; + } + } + class NewChatNavigationError extends Error { + code = 'NEW_CHAT_NAVIGATION_FAILED'; + reason = 'new-chat-navigation-failed'; + delivery = 'rejected'; + constructor(project, observed){ + super(`ChatGPT Desktop new-chat action did not open ${project ? `project ${JSON.stringify(project)}` : 'a projectless chat'}; observed ${observed}`); + this.name = 'NewChatNavigationError'; + } + } class NotImplementedError extends Error { code = 'NOT_IMPLEMENTED'; delivery = 'rejected'; @@ -13236,7 +13331,9 @@ var __webpack_modules__ = { } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, + Kn: ()=>ProjectUnavailableError, Rg: ()=>_codex_remote_control_js__rspack_import_0.Rg, + XL: ()=>NewChatNavigationError, c$: ()=>CdpHostRejectedError, fw: ()=>ArchivedThreadError, oN: ()=>ComposerDraftError, @@ -13244,37 +13341,39 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/facade.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var _cdp_adapter_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-adapter.ts"); - var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); - var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); - var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); - var _remote_threads_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); - var _payload_budget_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); - var _thread_ids_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var node_crypto__rspack_import_0 = __webpack_require__("node:crypto"); + var _cdp_adapter_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-adapter.ts"); + var _app_server_fallback_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); + var _errors_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _loopback_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _remote_threads_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _project_state_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/project-state.ts"); + var _payload_budget_js__rspack_import_8 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); + var _thread_ids_js__rspack_import_7 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { - listThreads: _app_server_fallback_js__rspack_import_1.OI, - searchThreads: _app_server_fallback_js__rspack_import_1.aI, - readThread: _app_server_fallback_js__rspack_import_1.Jf, - unarchiveThread: _app_server_fallback_js__rspack_import_1.qL, - statusProbe: _app_server_fallback_js__rspack_import_1.dM, - listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, - listHosts: _remote_threads_js__rspack_import_4.Kl, - discoverModelProviders: _app_server_fallback_js__rspack_import_1.X + listThreads: _app_server_fallback_js__rspack_import_2.OI, + searchThreads: _app_server_fallback_js__rspack_import_2.aI, + readThread: _app_server_fallback_js__rspack_import_2.Jf, + unarchiveThread: _app_server_fallback_js__rspack_import_2.qL, + statusProbe: _app_server_fallback_js__rspack_import_2.dM, + listRemoteThreads: _remote_threads_js__rspack_import_5.Hx, + listHosts: _remote_threads_js__rspack_import_5.Kl, + discoverModelProviders: _app_server_fallback_js__rspack_import_2.X }; - const REMOTE_PAGE_CURSOR = 'desktop-remote-page:'; - const APP_START_CURSOR = 'desktop-app-start'; + const MERGED_LIST_CURSOR = 'desktop-merged-list-v1:'; class ChatGptDesktopFacade { #cdp; #port; #cdpConnected = false; #fallbacks; - constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)(), fallbacks = defaultFallbacks){ + #listSnapshots = new Map(); + constructor(cdp = new _cdp_adapter_js__rspack_import_1.a(), port = (0, _loopback_js__rspack_import_4.L0)(), fallbacks = defaultFallbacks){ this.#cdp = cdp; this.#port = port; this.#fallbacks = fallbacks; } async connect({ port }) { - this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); try { await this.#cdp.connect({ port: this.#port @@ -13291,124 +13390,195 @@ var __webpack_modules__ = { } async listThreads(options = {}) { const limit = options.limit ?? 50; + const filters = JSON.stringify({ + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || null, + project: options.project?.trim() || null, + groupBy: options.groupBy ?? null + }); + let snapshot; + let offset = 0; + if (options.cursor) { + const state = (0, _payload_budget_js__rspack_import_8.i3)(MERGED_LIST_CURSOR, options.cursor); + if (state.port !== this.#port || state.filters !== filters || !Number.isSafeInteger(state.offset) || state.offset < 1 || typeof state.fingerprint !== 'string') { + throw new Error('ChatGPT Desktop list cursor does not match the port or filters'); + } + offset = state.offset; + snapshot = this.#listSnapshots.get(state.fingerprint) ?? await this.#buildListSnapshot(options, filters); + if (snapshot.fingerprint !== state.fingerprint || snapshot.filters !== filters || snapshot.port !== this.#port) { + throw new Error('ChatGPT Desktop thread inventory changed; restart listing without a cursor'); + } + } else { + snapshot = await this.#buildListSnapshot(options, filters); + } + if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop list cursor is out of range'); const host = normalizeHostFilter(options.host); - const modelProviders = modelProvidersFromFilter(options.modelProvider); - const remoteOffset = options.cursor?.startsWith(REMOTE_PAGE_CURSOR) ? Number(options.cursor.slice(REMOTE_PAGE_CURSOR.length)) : null; - if (remoteOffset !== null && (!Number.isSafeInteger(remoteOffset) || remoteOffset < 1)) { - throw new Error('Invalid ChatGPT Desktop remote page cursor'); + const rows = []; + const base = { + backend: snapshot.backend, + limit, + host, + ...options.modelProvider?.trim() ? { + modelProvider: options.modelProvider.trim() + } : {}, + ...options.project ? { + project: options.project + } : {}, + ...options.groupBy === 'host' ? { + groupBy: 'host' + } : {} + }; + for (const source of snapshot.rows.slice(offset, offset + limit)){ + let row = source; + const candidate = [ + ...rows, + row + ]; + const probe = { + ...base, + threads: candidate, + nextCursor: MERGED_LIST_CURSOR, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost(candidate) + } : {}, + warnings: snapshot.warnings, + exitCode: 0 + }; + if ((0, _payload_budget_js__rspack_import_8.sQ)(probe) > 614400) { + if (rows.length) break; + row = (0, _payload_budget_js__rspack_import_8.MH)(row); + const minimal = [ + row + ]; + if ((0, _payload_budget_js__rspack_import_8.sQ)({ + ...base, + threads: minimal, + nextCursor: MERGED_LIST_CURSOR, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost(minimal) + } : {}, + warnings: snapshot.warnings, + exitCode: 0 + }) > 614400) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + rows.push(row); } - const inventoryPage = !options.cursor || remoteOffset !== null; - const remotes = inventoryPage ? this.#listRemotes() : []; - let cdpList = null; - let cdpError; + const nextOffset = offset + rows.length; + const nextCursor = nextOffset < snapshot.rows.length ? (0, _payload_budget_js__rspack_import_8.oI)(MERGED_LIST_CURSOR, { + fingerprint: snapshot.fingerprint, + offset: nextOffset, + port: this.#port, + filters + }) : null; + const warnings = [ + ...snapshot.warnings + ]; + if (rows.length < Math.min(limit, snapshot.rows.length - offset)) { + warnings.push('List page stopped at the MCP byte budget; continue with nextCursor'); + } + return { + ...base, + threads: rows, + nextCursor, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost(rows) + } : {}, + ...warnings.length ? { + warnings + } : {} + }; + } + async #buildListSnapshot(options, filters) { + const appRows = []; + const warnings = []; + let appCursor; + let appComplete = false; + const seenCursors = new Set(); + const modelProviders = modelProvidersFromFilter(options.modelProvider); try { - if (inventoryPage) { - await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads({ - limit: 200 + for(let page = 0; page < 400; page++){ + const out = await this.#fallbacks.listThreads({ + limit: 200, + cursor: appCursor, + modelProviders }); - } - } catch (error) { - if (isCdpFailure(error)) { - this.#cdpConnected = false; - } else { - cdpError = error; - } - } - if (inventoryPage && host !== 'local') { - const remoteInventory = finalizeThreadList({ - backend: cdpList?.backend ?? 'remote-state', - limit: 10000, - threads: cdpList?.threads.filter((thread)=>thread.location === 'remote') ?? [] - }, { - limit: 10000, - host, - modelProvider: options.modelProvider, - project: options.project, - remotes - }); - const offset = remoteOffset ?? 0; - if (remoteOffset !== null || remoteInventory.threads.length >= limit) { - const page = []; - for (const thread of remoteInventory.threads.slice(offset, offset + limit)){ - const row = (0, _payload_budget_js__rspack_import_6.eX)(thread); - if ((0, _payload_budget_js__rspack_import_6.sQ)({ - ...remoteInventory, - threads: [ - ...page, - row - ], - nextCursor: REMOTE_PAGE_CURSOR, - ...options.groupBy === 'host' ? { - groups: groupThreadsByHost([ - ...page, - row - ]) - } : {} - }) > 614400) { - if (!page.length) throw new Error('ChatGPT Desktop remote thread row exceeds the MCP result byte budget'); - break; - } - page.push(row); + appRows.push(...out.threads); + if (out.warnings) warnings.push(...out.warnings); + if (!out.nextCursor) { + appComplete = true; + break; } - const nextOffset = offset + page.length; - const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; - return { - ...remoteInventory, - threads: page, - limit, - nextCursor, - ...options.groupBy === 'host' ? { - groupBy: 'host', - groups: groupThreadsByHost(page) - } : {} - }; + if (seenCursors.has(out.nextCursor)) throw new Error('App-server list returned a repeated cursor'); + seenCursors.add(out.nextCursor); + appCursor = out.nextCursor; } + if (!appComplete) warnings.push('App-server inventory stopped after 400 pages'); + } catch (error) { + warnings.push(`App-server list failed: ${error instanceof Error ? error.message : String(error)}`); } - const remoteKeys = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); - const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; - const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); - let appList = null; - let appError; + const remotes = this.#listRemotes(); + let cdpList = null; try { - appList = await this.#fallbacks.listThreads({ - limit: appLimit, - cursor: options.cursor === APP_START_CURSOR ? undefined : options.cursor, - modelProviders + await this.#ensureCdp(); + cdpList = await this.#cdp.listThreads({ + limit: 200 }); } catch (error) { - appError = error; - } - let base = null; - if (appList && cdpList) base = mergeThreadLists(appList, cdpList); - else if (appList) base = appList; - else if (cdpList) base = cdpList; - else if (remotes.length) base = { - backend: 'remote-state', - limit, - threads: [] + if (isCdpFailure(error)) this.#cdpConnected = false; + else warnings.push(`CDP list failed: ${error instanceof Error ? error.message : String(error)}`); + } + if (!appRows.length && !cdpList && !remotes.length) { + throw new _errors_js__rspack_import_3.sO(warnings[0] ?? 'ChatGPT Desktop listThreads: CDP and app-server unreachable'); + } + const appList = { + backend: 'app-server', + limit: appRows.length, + threads: appRows }; - else if (cdpError) throw cdpError; - else if (appError) throw appError; - else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); - const result = finalizeThreadList(base, { - limit, - host, + const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const merged = finalizeThreadList({ + ...base, + threads: (0, _project_state_js__rspack_import_6.j)(base.threads) + }, { + limit: Number.MAX_SAFE_INTEGER, + host: normalizeHostFilter(options.host), modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - groupBy: options.groupBy, - remotes + remotes: (0, _project_state_js__rspack_import_6.j)(remotes) }); - const withCursor = host === 'all' || host === 'local' ? result : { - ...result, - nextCursor: null + const rows = [ + ...new Map(merged.threads.map((row)=>[ + (0, _thread_ids_js__rspack_import_7.nn)(row.threadId) ?? row.threadId, + row + ])).values() + ]; + rows.sort(compareDesktopThreads); + const fingerprint = (0, node_crypto__rspack_import_0.createHash)('sha256').update(JSON.stringify({ + filters, + port: this.#port, + rows: rows.map((row)=>[ + row.threadId, + row.updatedAt, + row.location, + row.hostId + ]) + })).digest('base64url'); + const snapshot = { + fingerprint, + port: this.#port, + filters, + createdAt: Date.now(), + rows, + backend: merged.backend, + warnings }; - return appError ? { - ...withCursor, - warnings: [ - `App-server list failed: ${appError instanceof Error ? appError.message : String(appError)}` - ] - } : withCursor; + for (const [key, value] of this.#listSnapshots){ + if (Date.now() - value.createdAt > 15 * 60000 || this.#listSnapshots.size >= 8) this.#listSnapshots.delete(key); + } + this.#listSnapshots.set(fingerprint, snapshot); + return snapshot; } async listHosts() { const remotes = this.#listRemotes(); @@ -13425,7 +13595,7 @@ var __webpack_modules__ = { } catch { localThreadCount = 0; } - const listHosts = this.#fallbacks.listHosts ?? _remote_threads_js__rspack_import_4.Kl; + const listHosts = this.#fallbacks.listHosts ?? _remote_threads_js__rspack_import_5.Kl; const fromState = listHosts(process.env, { localThreadCount }); @@ -13490,7 +13660,7 @@ var __webpack_modules__ = { let modelProvidersSource = 'thread/list-distinct'; const warnings = []; try { - const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_1.X; + const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_2.X; const discovered = await discover(); modelProviders = [ ...discovered.providers @@ -13511,14 +13681,35 @@ var __webpack_modules__ = { ...remotes.map((thread)=>thread.modelProvider).filter((value)=>Boolean(value)) ]) ].sort(); + let inventoryCounts = null; + try { + const filters = JSON.stringify({ + host: 'all', + modelProvider: null, + project: null, + groupBy: null + }); + const cached = [ + ...this.#listSnapshots.values() + ].find((snapshot)=>snapshot.port === this.#port && snapshot.filters === filters && Date.now() - snapshot.createdAt < 15 * 60000); + const inventory = cached ?? await this.#buildListSnapshot({}, filters); + inventoryCounts = new Map(); + for (const thread of inventory.rows){ + const hostId = thread.location === 'remote' ? thread.hostId ?? 'unknown-remote' : 'local'; + inventoryCounts.set(hostId, (inventoryCounts.get(hostId) ?? 0) + 1); + } + warnings.push(...inventory.warnings); + } catch (error) { + warnings.push(`Merged inventory count failed: ${error instanceof Error ? error.message : String(error)}`); + } return { hosts: withCounts.map((host)=>{ - const counted = host.hostId === 'local' ? { + const counted = { ...host, - threadCount: localThreadCount - } : host; + threadCount: inventoryCounts?.get(host.hostId) ?? (host.hostId === 'local' ? localThreadCount : host.threadCount) + }; if (!counted.hostName) return counted; - const name = (0, _payload_budget_js__rspack_import_6.aA)(counted.hostName); + const name = (0, _payload_budget_js__rspack_import_8.aA)(counted.hostName); return { ...counted, hostName: name.title, @@ -13545,20 +13736,22 @@ var __webpack_modules__ = { query: options.query, limit, cursor: options.cursor, - modelProviders, - project: options.project + modelProviders }); const cdpList = options.cursor ? null : await this.#tryCdpList({ limit }); const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; const appMatches = new Set(appList.threads.map((thread)=>thread.threadId)); - const withRemotes = finalizeThreadList(base, { + const withRemotes = finalizeThreadList({ + ...base, + threads: (0, _project_state_js__rspack_import_6.j)(base.threads) + }, { limit: 10000, host, modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - remotes: options.cursor ? [] : this.#listRemotes() + remotes: options.cursor ? [] : (0, _project_state_js__rspack_import_6.j)(this.#listRemotes()) }); const needle = options.query.trim().toLowerCase(); const filtered = { @@ -13589,7 +13782,7 @@ var __webpack_modules__ = { limit }, query: options.query, - threads: (cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) + threads: (0, _project_state_js__rspack_import_6.j)(cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) }; const result = finalizeThreadList(filtered, { limit, @@ -13597,7 +13790,7 @@ var __webpack_modules__ = { modelProvider: options.modelProvider?.trim() || undefined, project: options.project, groupBy: options.groupBy, - remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) + remotes: (0, _project_state_js__rspack_import_6.j)(remotes).filter((thread)=>threadMatchesQuery(thread, needle)) }); return { ...result, @@ -13610,7 +13803,7 @@ var __webpack_modules__ = { async readThread(options) { const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; - if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { + if ((0, _thread_ids_js__rspack_import_7.vr)(options.threadId)) { if (options.cursor) throw new Error('Temporary Desktop threads do not support read cursors'); await this.#ensureCdp(); return this.#cdp.readThread({ @@ -13627,7 +13820,7 @@ var __webpack_modules__ = { cursor: options.cursor }); } catch (appError) { - if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; + if (appError instanceof _errors_js__rspack_import_3.Rg) throw appError; if (options.cursor) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; @@ -13647,15 +13840,15 @@ var __webpack_modules__ = { } async sendMessage(options) { if (options.threadId) { - const remote = (0, _remote_threads_js__rspack_import_4.KI)(options.threadId); - if (remote) throw new _errors_js__rspack_import_2.Rg(options.threadId, remote.hostId, remote.hostName); + const remote = (0, _remote_threads_js__rspack_import_5.KI)(options.threadId); + if (remote) throw new _errors_js__rspack_import_3.Rg(options.threadId, remote.hostId, remote.hostName); } await this.#ensureCdp(); try { return await this.#cdp.sendMessage(options); } catch (error) { - if (!(error instanceof _errors_js__rspack_import_2.fw) || !options.unarchive || !options.threadId) throw error; - await (this.#fallbacks.unarchiveThread ?? _app_server_fallback_js__rspack_import_1.qL)(options.threadId); + if (!(error instanceof _errors_js__rspack_import_3.fw) || !options.unarchive || !options.threadId) throw error; + await (this.#fallbacks.unarchiveThread ?? _app_server_fallback_js__rspack_import_2.qL)(options.threadId); return this.#cdp.sendMessage({ ...options, unarchive: false @@ -13667,8 +13860,8 @@ var __webpack_modules__ = { return this.#cdp.waitForReply(options); } async openThread(threadId, options) { - const remote = (0, _remote_threads_js__rspack_import_4.KI)(threadId); - if (remote) throw new _errors_js__rspack_import_2.Rg(threadId, remote.hostId, remote.hostName); + const remote = (0, _remote_threads_js__rspack_import_5.KI)(threadId); + if (remote) throw new _errors_js__rspack_import_3.Rg(threadId, remote.hostId, remote.hostName); await this.#ensureCdp(); return this.#cdp.openThread(threadId, options); } @@ -13697,7 +13890,7 @@ var __webpack_modules__ = { await this.#cdp.close(); } #listRemotes() { - const list = this.#fallbacks.listRemoteThreads ?? _remote_threads_js__rspack_import_4.Hx; + const list = this.#fallbacks.listRemoteThreads ?? _remote_threads_js__rspack_import_5.Hx; try { return list(); } catch { @@ -13726,7 +13919,7 @@ var __webpack_modules__ = { await this.#ensureCdp(); return await this.#cdp.listThreads(options); } catch (error) { - if (isCdpFailure(error) || error instanceof _errors_js__rspack_import_2.EH) { + if (isCdpFailure(error) || error instanceof _errors_js__rspack_import_3.EH) { if (isCdpFailure(error)) this.#cdpConnected = false; return null; } @@ -13737,11 +13930,11 @@ var __webpack_modules__ = { function mergeThreadLists(appList, cdpList) { const cdpByKey = new Map(); for (const thread of cdpList.threads){ - const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId; cdpByKey.set(key, thread); } const merged = appList.threads.map((thread)=>{ - const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId; const cdp = cdpByKey.get(key); const withLocal = { ...thread, @@ -13763,7 +13956,7 @@ var __webpack_modules__ = { }; }); for (const thread of cdpList.threads){ - if (merged.some((row)=>(0, _thread_ids_js__rspack_import_5.LV)(row.threadId, thread.threadId))) continue; + if (merged.some((row)=>(0, _thread_ids_js__rspack_import_7.LV)(row.threadId, thread.threadId))) continue; merged.push(thread); } return { @@ -13778,11 +13971,11 @@ var __webpack_modules__ = { } function finalizeThreadList(base, { limit, host = 'all', modelProvider, project, groupBy, remotes }) { const remoteById = new Map(remotes.map((thread)=>[ - (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId, + (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId, thread ])); const locals = base.threads.map((thread)=>{ - const remote = remoteById.get((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId); + const remote = remoteById.get((0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId); if (remote) { return { ...thread, @@ -13799,12 +13992,12 @@ var __webpack_modules__ = { hostName: location === 'remote' ? thread.hostName ?? null : null }; }); - const localKeys = new Set(locals.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + const localKeys = new Set(locals.map((thread)=>(0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId)); const merged = [ ...locals ]; for (const remote of remotes){ - const key = (0, _thread_ids_js__rspack_import_5.nn)(remote.threadId) ?? remote.threadId; + const key = (0, _thread_ids_js__rspack_import_7.nn)(remote.threadId) ?? remote.threadId; if (localKeys.has(key)) continue; merged.push({ ...remote, @@ -13812,6 +14005,7 @@ var __webpack_modules__ = { hostId: remote.hostId ?? null, hostName: remote.hostName ?? null }); + localKeys.add(key); } if (remotes.length) merged.sort((a, b)=>Number(b.location === 'remote') - Number(a.location === 'remote')); const filtered = merged.filter((thread)=>{ @@ -13820,7 +14014,7 @@ var __webpack_modules__ = { if (!projectMatches(thread, project)) return false; return true; }); - const limited = filtered.slice(0, limit).map(_payload_budget_js__rspack_import_6.eX); + const limited = filtered.slice(0, limit).map(_payload_budget_js__rspack_import_8.eX); const result = { backend: remotes.length ? base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' : base.backend === 'app-server' ? 'app-server+remote-state' : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend : base.backend, limit, @@ -13848,6 +14042,14 @@ var __webpack_modules__ = { } return result; } + function compareDesktopThreads(a, b) { + const timestamp = (row)=>{ + const value = row.updatedAt ?? row.createdAt; + if (typeof value !== 'number' || !Number.isFinite(value)) return Number.NEGATIVE_INFINITY; + return value < 100000000000 ? value * 1000 : value; + }; + return timestamp(b) - timestamp(a) || a.threadId.localeCompare(b.threadId); + } function groupThreadsByHost(threads) { const groups = new Map(); for (const thread of threads){ @@ -13915,8 +14117,8 @@ var __webpack_modules__ = { ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); } function isCdpFailure(error) { - if (error instanceof _errors_js__rspack_import_2.sO) return true; - if (error instanceof _errors_js__rspack_import_2.EH) return false; + if (error instanceof _errors_js__rspack_import_3.sO) return true; + if (error instanceof _errors_js__rspack_import_3.EH) return false; if (error && typeof error === 'object' && 'code' in error) { const code = String(error.code); return code === 'CDP_UNREACHABLE' || code === 'CDP_HOST_REJECTED'; @@ -14090,6 +14292,102 @@ var __webpack_modules__ = { sQ: ()=>serializedBytes }); }, + "./src/core/chatgpt-desktop/project-state.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + function findLocalProject(nameOrId, env = process.env) { + const state = (0, _codex_remote_control_js__rspack_import_0.IT)(env); + if (!state) return null; + for (const value of Object.values(record(stateValue(state, 'local-projects')) ?? {})){ + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.name !== 'string') continue; + if (row.id !== nameOrId && row.name.toLowerCase() !== nameOrId.toLowerCase()) continue; + return { + id: row.id, + label: row.name, + rootPaths: (Array.isArray(row.rootPaths) ? row.rootPaths : []).filter((path)=>typeof path === 'string' && Boolean(path)) + }; + } + return null; + } + function record(value) { + return value && typeof value === 'object' && !Array.isArray(value) ? value : null; + } + function stateValue(state, key) { + for (const source of (0, _codex_remote_control_js__rspack_import_0.xr)(state))if (key in source) return source[key]; + return undefined; + } + function pathWithin(path, root) { + const normalized = root.replace(/\/+$/u, ''); + return path === normalized || path.startsWith(`${normalized}/`); + } + function resolveThreadProjects(threads, env = process.env) { + const state = (0, _codex_remote_control_js__rspack_import_0.IT)(env); + if (!state) return [ + ...threads + ]; + const localProjects = Object.values(record(stateValue(state, 'local-projects')) ?? {}).flatMap((value)=>{ + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.name !== 'string') return []; + return (Array.isArray(row.rootPaths) ? row.rootPaths : []).filter((path)=>typeof path === 'string' && Boolean(path)).map((rootPath)=>({ + id: row.id, + label: row.name, + rootPath + })); + }); + const remoteProjects = (Array.isArray(stateValue(state, 'remote-projects')) ? stateValue(state, 'remote-projects') : []).flatMap((value)=>{ + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.label !== 'string' || typeof row.remotePath !== 'string' || typeof row.hostId !== 'string') return []; + return [ + { + id: row.id, + label: row.label, + rootPath: row.remotePath, + hostId: row.hostId + } + ]; + }); + const assignments = record(stateValue(state, 'thread-project-assignments')) ?? {}; + const hints = record(stateValue(state, 'thread-workspace-root-hints')) ?? {}; + const projectless = new Set(Array.isArray(stateValue(state, 'projectless-thread-ids')) ? stateValue(state, 'projectless-thread-ids') : []); + return threads.map((thread)=>{ + const bare = (0, _thread_ids_js__rspack_import_1.nn)(thread.threadId) ?? thread.threadId; + const assignment = record(assignments[bare]); + const remote = thread.location === 'remote'; + const projects = remote ? remoteProjects.filter((project)=>project.hostId === thread.hostId) : localProjects; + let project = assignment && typeof assignment.projectId === 'string' ? projects.find((entry)=>entry.id === assignment.projectId) : undefined; + if (!project && !projectless.has(bare) && thread.projectId) { + project = projects.find((entry)=>entry.id === thread.projectId); + } + if (!project && !assignment && !projectless.has(bare)) { + const path = typeof hints[bare] === 'string' ? hints[bare] : typeof thread.cwd === 'string' ? thread.cwd : null; + if (path) project = projects.filter((entry)=>pathWithin(path, entry.rootPath)).sort((a, b)=>b.rootPath.length - a.rootPath.length)[0]; + } + if (project) return { + ...thread, + project: project.label, + projectId: project.id, + projectRootPath: project.rootPath + }; + if (projectless.has(bare)) return { + ...thread, + project: null, + projectId: null + }; + if (remote && typeof thread.project === 'string' && thread.project.startsWith('/')) { + return { + ...thread, + project: null + }; + } + return thread; + }); + } + __webpack_require__.d(__webpack_exports__, { + j: ()=>resolveThreadProjects, + q: ()=>findLocalProject + }); + }, "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index 28ad6f6..fbbaaed 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -9827,69 +9827,96 @@ var __webpack_modules__ = { let fetchLimit = Math.min(limit, 25); if (cursor?.startsWith(LIST_PAGE_PREFIX)) { const state = (0, _payload_budget_js__rspack_import_4.i3)(LIST_PAGE_PREFIX, cursor); - if (!Number.isSafeInteger(state.skip) || state.skip < 1 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || state.cursor !== null && typeof state.cursor !== 'string') { + if (!Number.isSafeInteger(state.skip) || state.skip < 0 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || state.cursor !== null && typeof state.cursor !== 'string') { throw new Error('Invalid ChatGPT Desktop list page cursor'); } sourceCursor = state.cursor ?? undefined; skip = state.skip; fetchLimit = state.fetchLimit; } - const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit: fetchLimit, - cursor: sourceCursor, - modelProviders - }); - if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); const base = { backend: 'app-server', limit, modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; const threads = []; - let consumed = skip; - for (const raw of out.threads.slice(skip)){ - if (threads.length >= limit) break; - let row = (0, _payload_budget_js__rspack_import_4.eX)(mapListedThread(raw)); - const probe = { - ...base, - threads: [ - ...threads, - row - ], - nextCursor: LIST_PAGE_PREFIX, - exitCode: 0 - }; - if ((0, _payload_budget_js__rspack_import_4.sQ)(probe) > 614400) { - if (threads.length) break; - row = (0, _payload_budget_js__rspack_import_4.MH)(row); - if ((0, _payload_budget_js__rspack_import_4.sQ)({ + const seen = new Set(); + for(let page = 0; page < 400; page++){ + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit: fetchLimit, + cursor: sourceCursor, + modelProviders + }); + if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); + for(let index = skip; index < out.threads.length; index++){ + let row = (0, _payload_budget_js__rspack_import_4.eX)(mapListedThread(out.threads[index])); + const probe = { ...base, threads: [ + ...threads, row ], nextCursor: LIST_PAGE_PREFIX, exitCode: 0 - }) > 614400) { - throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + }; + if ((0, _payload_budget_js__rspack_import_4.sQ)(probe) > 614400) { + if (threads.length) return { + ...base, + threads, + nextCursor: (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { + cursor: sourceCursor ?? null, + skip: index, + fetchLimit + }), + warnings: [ + 'List page stopped at the MCP byte budget; continue with nextCursor' + ] + }; + row = (0, _payload_budget_js__rspack_import_4.MH)(row); + if ((0, _payload_budget_js__rspack_import_4.sQ)({ + ...base, + threads: [ + row + ], + nextCursor: LIST_PAGE_PREFIX, + exitCode: 0 + }) > 614400) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + threads.push(row); + if (threads.length >= limit) { + const nextCursor = index + 1 < out.threads.length ? (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { + cursor: sourceCursor ?? null, + skip: index + 1, + fetchLimit + }) : out.nextCursor ?? null; + return { + ...base, + threads, + nextCursor + }; } } - threads.push(row); - consumed++; + if (out.nextCursor == null) return { + ...base, + threads, + nextCursor: null + }; + if (typeof out.nextCursor !== 'string' || !out.nextCursor || seen.has(out.nextCursor)) { + throw new Error('ChatGPT Desktop list returned an invalid or repeated cursor'); + } + seen.add(out.nextCursor); + sourceCursor = out.nextCursor; + skip = 0; } - const nextCursor = consumed < out.threads.length ? (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { - cursor: sourceCursor ?? null, - skip: consumed, - fetchLimit - }) : out.nextCursor ?? null; return { ...base, threads, - nextCursor, - ...consumed < out.threads.length ? { - warnings: [ - 'List page stopped at the MCP byte budget; continue with nextCursor' - ] - } : {} + nextCursor: sourceCursor, + warnings: [ + 'List stopped after 400 app-server pages; continue with nextCursor' + ] }; } async function appServerSearchThreads({ query, limit = 50, cursor, modelProviders = [], project }) { @@ -10488,13 +10515,15 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); - var _cdp_session_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); - var _cdp_dom_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); - var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); - var _loopback_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _cdp_session_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); + var _cdp_dom_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); + var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _loopback_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _project_state_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/project-state.ts"); class CdpChatGptDesktopAdapter { - #port = (0, _loopback_js__rspack_import_4.L0)(); + #port = (0, _loopback_js__rspack_import_5.L0)(); #session = null; #version = null; #pageSessionId = null; @@ -10502,8 +10531,8 @@ var __webpack_modules__ = { #submittedTurn = null; async connect({ port }) { await this.close(); - this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); - const session = new _cdp_session_js__rspack_import_1.a(this.#port); + this.#port = (0, _loopback_js__rspack_import_5.L0)(process.env, port); + const session = new _cdp_session_js__rspack_import_2.a(this.#port); try { this.#version = await session.connect(); this.#session = session; @@ -10517,11 +10546,11 @@ var __webpack_modules__ = { async listTargets() { const session = this.#requireSession(); const result = await session.send('Target.getTargets'); - return (0, _cdp_dom_js__rspack_import_2.Mr)(result.targetInfos ?? []); + return (0, _cdp_dom_js__rspack_import_3.Mr)(result.targetInfos ?? []); } async listThreads({ limit = 50 } = {}) { const sessionId = await this.#ensurePageSession(); - const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + const threads = await (0, _cdp_dom_js__rspack_import_3.AY)(this.#requireSession(), sessionId, { limit }); return { @@ -10533,7 +10562,7 @@ var __webpack_modules__ = { async readThread({ threadId, limit = 100, full = false, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); await this.#openAndWait(sessionId, threadId, openTimeoutMs); - const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + const turns = await (0, _cdp_dom_js__rspack_import_3.JU)(this.#requireSession(), sessionId, { limit, full, threadId @@ -10554,26 +10583,27 @@ var __webpack_modules__ = { if (threadId) { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } else { - await (0, _cdp_dom_js__rspack_import_2.s0)(this.#requireSession(), sessionId, { - project - }); - await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { - timeoutMs: openTimeoutMs, - threadId: 'new' + const localProject = project ? (0, _project_state_js__rspack_import_6.q)(project) : null; + if (localProject && !localProject.rootPaths.some((path)=>(0, node_fs__rspack_import_0.existsSync)(path))) { + throw new _errors_js__rspack_import_1.Kn(localProject.label, `none of its configured workspace roots exists: ${localProject.rootPaths.map((path)=>JSON.stringify(path)).join(', ') || '(none)'}. Update the Desktop project root before sending.`); + } + await (0, _cdp_dom_js__rspack_import_3.s0)(this.#requireSession(), sessionId, { + project: localProject?.label ?? project, + projectId: localProject?.id }); - const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + const threads = await (0, _cdp_dom_js__rspack_import_3.AY)(this.#requireSession(), sessionId, { limit: 20 }); - const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); + const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_3.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_3.hA)); if (temp) temporaryThreadId = temp.threadId; } - const before = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); - const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + const before = await (0, _cdp_dom_js__rspack_import_3.YX)(this.#requireSession(), sessionId); + const { sentVia } = await (0, _cdp_dom_js__rspack_import_3.lh)(this.#requireSession(), sessionId, text); let conversationId; - if (startedNew || threadId && (0, _thread_ids_js__rspack_import_3.vr)(threadId)) { + if (startedNew || threadId && (0, _thread_ids_js__rspack_import_4.vr)(threadId)) { const resolveMs = Math.min(openTimeoutMs, 60000); try { - conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { + conversationId = await (0, _cdp_dom_js__rspack_import_3.z9)(this.#requireSession(), sessionId, { timeoutMs: resolveMs }); } catch (error) { @@ -10583,7 +10613,7 @@ var __webpack_modules__ = { }); } } - const durable = (0, _cdp_dom_js__rspack_import_2.X8)(conversationId, threadId); + const durable = (0, _cdp_dom_js__rspack_import_3.X8)(conversationId, threadId); if (!durable) { throw new Error('ChatGPT Desktop send accepted but no durable conversation id was available; ' + 'refusing to return a local:client-new-thread:* id as threadId'); } @@ -10594,7 +10624,7 @@ var __webpack_modules__ = { return { threadId: durable, temporaryThreadId, - conversationId: conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, + conversationId: conversationId || (0, _thread_ids_js__rspack_import_4.nn)(durable) || durable, project, backend: 'cdp', experimental: false, @@ -10606,30 +10636,30 @@ var __webpack_modules__ = { async waitForReply({ threadId, timeoutMs = 120000 }) { const deadline = Date.now() + timeoutMs; const sessionId = await this.#ensurePageSession(); - const expectedId = threadId && threadId !== 'new' ? (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? undefined : this.#submittedTurn ? (0, _thread_ids_js__rspack_import_3.nn)(this.#submittedTurn.threadId) ?? undefined : undefined; - if (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) && threadId !== 'new') { + const expectedId = threadId && threadId !== 'new' ? (0, _thread_ids_js__rspack_import_4.nn)(threadId) ?? undefined : this.#submittedTurn ? (0, _thread_ids_js__rspack_import_4.nn)(this.#submittedTurn.threadId) ?? undefined : undefined; + if (threadId && !(0, _thread_ids_js__rspack_import_4.vr)(threadId) && threadId !== 'new') { await this.#openAndWait(sessionId, threadId, Math.min(timeoutMs, 90000)); } try { - const done = await (0, _cdp_dom_js__rspack_import_2.FG)(this.#requireSession(), sessionId, { + const done = await (0, _cdp_dom_js__rspack_import_3.FG)(this.#requireSession(), sessionId, { timeoutMs: Math.max(0, deadline - Date.now()), expectedConversationId: expectedId, - baselineTurnKey: this.#submittedTurn && (!threadId || (0, _thread_ids_js__rspack_import_3.BS)(threadId) === this.#submittedTurn.threadId) ? this.#submittedTurn.turnKey : undefined + baselineTurnKey: this.#submittedTurn && (!threadId || (0, _thread_ids_js__rspack_import_4.BS)(threadId) === this.#submittedTurn.threadId) ? this.#submittedTurn.turnKey : undefined }); - const durable = (0, _cdp_dom_js__rspack_import_2.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_3.BS)(done.conversationId) : null); + const durable = (0, _cdp_dom_js__rspack_import_3.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_4.BS)(done.conversationId) : null); if (!durable) { throw new Error('ChatGPT Desktop reply finished without a durable conversation id on ' + '[data-response-annotation-conversation]'); } return { threadId: durable, - conversationId: done.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, + conversationId: done.conversationId || (0, _thread_ids_js__rspack_import_4.nn)(durable) || durable, reply: done.reply, backend: 'cdp', experimental: false, delivery: 'replied' }; } catch (error) { - if (!(error instanceof _cdp_dom_js__rspack_import_2.aw)) throw error; + if (!(error instanceof _cdp_dom_js__rspack_import_3.aw)) throw error; return { threadId: threadId ?? 'unknown', reply: '', @@ -10644,7 +10674,7 @@ var __webpack_modules__ = { try { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } catch (error) { - if (error instanceof _errors_js__rspack_import_0.fw) return { + if (error instanceof _errors_js__rspack_import_1.fw) return { threadId, backend: 'cdp', archived: true @@ -10658,15 +10688,15 @@ var __webpack_modules__ = { } async status() { try { - const version = this.#version ?? await _cdp_session_js__rspack_import_1.a.fetchVersion(this.#port); + const version = this.#version ?? await _cdp_session_js__rspack_import_2.a.fetchVersion(this.#port); let targetCount; let mainWindowTargetId; if (this.#session && !this.#session.closed) { const targets = await this.listTargets(); targetCount = targets.length; - mainWindowTargetId = (0, _cdp_dom_js__rspack_import_2.C2)(targets)?.targetId ?? null; + mainWindowTargetId = (0, _cdp_dom_js__rspack_import_3.C2)(targets)?.targetId ?? null; } else { - const list = await _cdp_session_js__rspack_import_1.a.fetchJsonList(this.#port); + const list = await _cdp_session_js__rspack_import_2.a.fetchJsonList(this.#port); targetCount = list.length; } return { @@ -10699,17 +10729,17 @@ var __webpack_modules__ = { this.#session = null; } async #openAndWait(sessionId, threadId, openTimeoutMs) { - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { + await (0, _cdp_dom_js__rspack_import_3.Kl)(this.#requireSession(), sessionId, threadId); + await (0, _cdp_dom_js__rspack_import_3.Zx)(this.#requireSession(), sessionId, { timeoutMs: openTimeoutMs, threadId }); } async #attachMainWindow() { const targets = await this.listTargets(); - const main = (0, _cdp_dom_js__rspack_import_2.C2)(targets); + const main = (0, _cdp_dom_js__rspack_import_3.C2)(targets); if (!main) { - throw new _errors_js__rspack_import_0.sO(`No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`); + throw new _errors_js__rspack_import_1.sO(`No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`); } const attached = await this.#requireSession().send('Target.attachToTarget', { targetId: main.targetId, @@ -10722,13 +10752,13 @@ var __webpack_modules__ = { this.#requireSession(); if (!this.#pageSessionId) await this.#attachMainWindow(); if (!this.#pageSessionId) { - throw new _errors_js__rspack_import_0.sO('Failed to attach to ChatGPT Desktop main window'); + throw new _errors_js__rspack_import_1.sO('Failed to attach to ChatGPT Desktop main window'); } return this.#pageSessionId; } #requireSession() { if (!this.#session || this.#session.closed) { - throw new _errors_js__rspack_import_0.sO('Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.'); + throw new _errors_js__rspack_import_1.sO('Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.'); } return this.#session; } @@ -10919,17 +10949,18 @@ var __webpack_modules__ = { return { ok: false, error: 'router-not-found' }; })()`; } - function startNewChatExpression(project) { + function startNewChatExpression(project, projectId) { const projectSel = project ? newChatInProjectSelector(project) : null; return `(() => { const projectSel = ${JSON.stringify(projectSel)}; if (projectSel) { - const preferred = document.querySelector(projectSel); + const preferred = ${projectId ? `document.querySelector('[data-app-action-sidebar-project-id=${JSON.stringify(projectId)}]')?.querySelector(projectSel) ||` : ''} document.querySelector(projectSel); if (preferred) { - const row = preferred.closest('.group') || preferred.parentElement; + const row = preferred.closest('[data-app-action-sidebar-project-row]') || preferred.parentElement; row?.scrollIntoView({ block: 'center' }); const rowBox = row?.getBoundingClientRect(); return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)}, + disabled: preferred.disabled || preferred.getAttribute('aria-disabled') === 'true', hoverX: rowBox?.left + rowBox?.width / 2, hoverY: rowBox?.top + rowBox?.height / 2 }; } return { ok: false, error: 'project-not-found' }; @@ -10941,15 +10972,40 @@ var __webpack_modules__ = { return { ok: true, via: 'fallback' }; })()`; } - function projectButtonBoxExpression(project) { + function projectButtonBoxExpression(project, projectId) { return `(() => { - const button = document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); + const button = ${projectId ? `document.querySelector('[data-app-action-sidebar-project-id=${JSON.stringify(projectId)}]')?.querySelector(${JSON.stringify(newChatInProjectSelector(project))}) ||` : ''} document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); if (!button) return null; const box = button.getBoundingClientRect(); return { x: box.left + box.width / 2, y: box.top + box.height / 2, - visible: box.width > 0 && box.height > 0 && getComputedStyle(button.parentElement).opacity !== '0' }; + disabled: button.disabled || button.getAttribute('aria-disabled') === 'true', + visible: box.width > 0 && box.height > 0 && box.x >= 0 && box.y >= 0 + && box.x < innerWidth && box.y < innerHeight && getComputedStyle(button.parentElement).opacity !== '0' }; + })()`; + } + function newChatViewExpression(project) { + return `(() => { + const root = window.__codexRoot?._internalRoot?.current; + const queue = [root]; let scanned = 0; let path = ''; + while (queue.length && scanned++ < 10000) { + const fiber = queue.shift(); if (!fiber) continue; + const router = fiber.memoizedProps?.router; + if (router?.navigate && router?.state?.location) { path = router.state.location.pathname; break; } + if (fiber.child) queue.push(fiber.child); + if (fiber.sibling) queue.push(fiber.sibling); + } + const composer = !!document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + const scope = document.querySelector('[data-composer-navigation-target="workspace-project"]')?.getAttribute('aria-label') || ''; + const expected = ${JSON.stringify(project ? `Change project: ${project}` : '')}; + return { ready: path === '/' && composer && (expected ? scope === expected : (!scope || scope === 'Choose project')), path, composer, scope }; })()`; } + const CLEAR_NEW_CHAT_PROJECT_EXPRESSION = `(() => { + const button = document.querySelector('[data-clear-project-button="true"]'); + if (!button || button.disabled) return false; + button.click(); + return true; +})()`; const LOADING_TASK_GONE_EXPRESSION = `(() => { const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); @@ -11135,14 +11191,15 @@ var __webpack_modules__ = { } throw new Error(loadingGone ? `ChatGPT Desktop timed out waiting for conversation ${JSON.stringify(threadId)}; displayed conversation ${JSON.stringify(lastConversationId)} after ${timeoutMs}ms` : `ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); } - async function startNewChatInDom(session, sessionId, { project } = {}) { - const result = await session.evaluate(startNewChatExpression(project), { + async function startNewChatInDom(session, sessionId, { project, projectId, navigationTimeoutMs = 3000 } = {}) { + const result = await session.evaluate(startNewChatExpression(project, projectId), { sessionId }); if (!result?.ok) { throw new Error(project ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` : 'ChatGPT Desktop "New chat" button not found'); } if (result.via === 'project') { + if (result.disabled) throw new _errors_js__rspack_import_0.Kn(project, 'the Desktop project new-chat action is disabled; check its configured workspace root'); if (![ result.hoverX, result.hoverY @@ -11156,9 +11213,10 @@ var __webpack_modules__ = { }, { sessionId }); - const button = await session.evaluate(projectButtonBoxExpression(project), { + const button = await session.evaluate(projectButtonBoxExpression(project, projectId), { sessionId }); + if (button?.disabled) throw new _errors_js__rspack_import_0.Kn(project, 'the Desktop project new-chat action is disabled; check its configured workspace root'); if (!button?.visible || !Number.isFinite(button.x) || !Number.isFinite(button.y)) { throw new Error(`ChatGPT Desktop project button did not appear after hover for ${JSON.stringify(project)}`); } @@ -11188,9 +11246,28 @@ var __webpack_modules__ = { sessionId }); } - return { - via: result.via ?? 'unknown' + let observed = { + ready: false, + path: '', + composer: false, + scope: '' }; + const deadline = Date.now() + navigationTimeoutMs; + while(Date.now() < deadline){ + observed = await session.evaluate(newChatViewExpression(project), { + sessionId + }); + if (observed?.ready) return { + via: result.via ?? 'unknown' + }; + if (!project && observed?.path === '/' && observed?.composer && observed.scope.startsWith('Change project: ')) { + await session.evaluate(CLEAR_NEW_CHAT_PROJECT_EXPRESSION, { + sessionId + }); + } + await delay(100); + } + throw new _errors_js__rspack_import_0.XL(project, `route ${JSON.stringify(observed?.path)}, composer ${Boolean(observed?.composer)}, project ${JSON.stringify(observed?.scope)}`); } async function focusComposer(session, sessionId) { const focused = await session.evaluate(FOCUS_COMPOSER_EXPRESSION, { @@ -11615,6 +11692,24 @@ var __webpack_modules__ = { this.name = 'ComposerDraftError'; } } + class ProjectUnavailableError extends Error { + code = 'PROJECT_UNAVAILABLE'; + reason = 'project-unavailable'; + delivery = 'rejected'; + constructor(project, detail){ + super(`ChatGPT Desktop cannot start a chat in project ${JSON.stringify(project)}: ${detail}`); + this.name = 'ProjectUnavailableError'; + } + } + class NewChatNavigationError extends Error { + code = 'NEW_CHAT_NAVIGATION_FAILED'; + reason = 'new-chat-navigation-failed'; + delivery = 'rejected'; + constructor(project, observed){ + super(`ChatGPT Desktop new-chat action did not open ${project ? `project ${JSON.stringify(project)}` : 'a projectless chat'}; observed ${observed}`); + this.name = 'NewChatNavigationError'; + } + } class NotImplementedError extends Error { code = 'NOT_IMPLEMENTED'; delivery = 'rejected'; @@ -11644,7 +11739,9 @@ var __webpack_modules__ = { } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, + Kn: ()=>ProjectUnavailableError, Rg: ()=>_codex_remote_control_js__rspack_import_0.Rg, + XL: ()=>NewChatNavigationError, c$: ()=>CdpHostRejectedError, fw: ()=>ArchivedThreadError, oN: ()=>ComposerDraftError, @@ -11652,37 +11749,39 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/facade.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var _cdp_adapter_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-adapter.ts"); - var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); - var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); - var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); - var _remote_threads_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); - var _payload_budget_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); - var _thread_ids_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var node_crypto__rspack_import_0 = __webpack_require__("node:crypto"); + var _cdp_adapter_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-adapter.ts"); + var _app_server_fallback_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); + var _errors_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _loopback_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _remote_threads_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _project_state_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/project-state.ts"); + var _payload_budget_js__rspack_import_8 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); + var _thread_ids_js__rspack_import_7 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { - listThreads: _app_server_fallback_js__rspack_import_1.OI, - searchThreads: _app_server_fallback_js__rspack_import_1.aI, - readThread: _app_server_fallback_js__rspack_import_1.Jf, - unarchiveThread: _app_server_fallback_js__rspack_import_1.qL, - statusProbe: _app_server_fallback_js__rspack_import_1.dM, - listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, - listHosts: _remote_threads_js__rspack_import_4.Kl, - discoverModelProviders: _app_server_fallback_js__rspack_import_1.X - }; - const REMOTE_PAGE_CURSOR = 'desktop-remote-page:'; - const APP_START_CURSOR = 'desktop-app-start'; + listThreads: _app_server_fallback_js__rspack_import_2.OI, + searchThreads: _app_server_fallback_js__rspack_import_2.aI, + readThread: _app_server_fallback_js__rspack_import_2.Jf, + unarchiveThread: _app_server_fallback_js__rspack_import_2.qL, + statusProbe: _app_server_fallback_js__rspack_import_2.dM, + listRemoteThreads: _remote_threads_js__rspack_import_5.Hx, + listHosts: _remote_threads_js__rspack_import_5.Kl, + discoverModelProviders: _app_server_fallback_js__rspack_import_2.X + }; + const MERGED_LIST_CURSOR = 'desktop-merged-list-v1:'; class ChatGptDesktopFacade { #cdp; #port; #cdpConnected = false; #fallbacks; - constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)(), fallbacks = defaultFallbacks){ + #listSnapshots = new Map(); + constructor(cdp = new _cdp_adapter_js__rspack_import_1.a(), port = (0, _loopback_js__rspack_import_4.L0)(), fallbacks = defaultFallbacks){ this.#cdp = cdp; this.#port = port; this.#fallbacks = fallbacks; } async connect({ port }) { - this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); try { await this.#cdp.connect({ port: this.#port @@ -11699,124 +11798,195 @@ var __webpack_modules__ = { } async listThreads(options = {}) { const limit = options.limit ?? 50; + const filters = JSON.stringify({ + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || null, + project: options.project?.trim() || null, + groupBy: options.groupBy ?? null + }); + let snapshot; + let offset = 0; + if (options.cursor) { + const state = (0, _payload_budget_js__rspack_import_8.i3)(MERGED_LIST_CURSOR, options.cursor); + if (state.port !== this.#port || state.filters !== filters || !Number.isSafeInteger(state.offset) || state.offset < 1 || typeof state.fingerprint !== 'string') { + throw new Error('ChatGPT Desktop list cursor does not match the port or filters'); + } + offset = state.offset; + snapshot = this.#listSnapshots.get(state.fingerprint) ?? await this.#buildListSnapshot(options, filters); + if (snapshot.fingerprint !== state.fingerprint || snapshot.filters !== filters || snapshot.port !== this.#port) { + throw new Error('ChatGPT Desktop thread inventory changed; restart listing without a cursor'); + } + } else { + snapshot = await this.#buildListSnapshot(options, filters); + } + if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop list cursor is out of range'); const host = normalizeHostFilter(options.host); - const modelProviders = modelProvidersFromFilter(options.modelProvider); - const remoteOffset = options.cursor?.startsWith(REMOTE_PAGE_CURSOR) ? Number(options.cursor.slice(REMOTE_PAGE_CURSOR.length)) : null; - if (remoteOffset !== null && (!Number.isSafeInteger(remoteOffset) || remoteOffset < 1)) { - throw new Error('Invalid ChatGPT Desktop remote page cursor'); + const rows = []; + const base = { + backend: snapshot.backend, + limit, + host, + ...options.modelProvider?.trim() ? { + modelProvider: options.modelProvider.trim() + } : {}, + ...options.project ? { + project: options.project + } : {}, + ...options.groupBy === 'host' ? { + groupBy: 'host' + } : {} + }; + for (const source of snapshot.rows.slice(offset, offset + limit)){ + let row = source; + const candidate = [ + ...rows, + row + ]; + const probe = { + ...base, + threads: candidate, + nextCursor: MERGED_LIST_CURSOR, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost(candidate) + } : {}, + warnings: snapshot.warnings, + exitCode: 0 + }; + if ((0, _payload_budget_js__rspack_import_8.sQ)(probe) > 614400) { + if (rows.length) break; + row = (0, _payload_budget_js__rspack_import_8.MH)(row); + const minimal = [ + row + ]; + if ((0, _payload_budget_js__rspack_import_8.sQ)({ + ...base, + threads: minimal, + nextCursor: MERGED_LIST_CURSOR, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost(minimal) + } : {}, + warnings: snapshot.warnings, + exitCode: 0 + }) > 614400) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + rows.push(row); } - const inventoryPage = !options.cursor || remoteOffset !== null; - const remotes = inventoryPage ? this.#listRemotes() : []; - let cdpList = null; - let cdpError; + const nextOffset = offset + rows.length; + const nextCursor = nextOffset < snapshot.rows.length ? (0, _payload_budget_js__rspack_import_8.oI)(MERGED_LIST_CURSOR, { + fingerprint: snapshot.fingerprint, + offset: nextOffset, + port: this.#port, + filters + }) : null; + const warnings = [ + ...snapshot.warnings + ]; + if (rows.length < Math.min(limit, snapshot.rows.length - offset)) { + warnings.push('List page stopped at the MCP byte budget; continue with nextCursor'); + } + return { + ...base, + threads: rows, + nextCursor, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost(rows) + } : {}, + ...warnings.length ? { + warnings + } : {} + }; + } + async #buildListSnapshot(options, filters) { + const appRows = []; + const warnings = []; + let appCursor; + let appComplete = false; + const seenCursors = new Set(); + const modelProviders = modelProvidersFromFilter(options.modelProvider); try { - if (inventoryPage) { - await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads({ - limit: 200 + for(let page = 0; page < 400; page++){ + const out = await this.#fallbacks.listThreads({ + limit: 200, + cursor: appCursor, + modelProviders }); - } - } catch (error) { - if (isCdpFailure(error)) { - this.#cdpConnected = false; - } else { - cdpError = error; - } - } - if (inventoryPage && host !== 'local') { - const remoteInventory = finalizeThreadList({ - backend: cdpList?.backend ?? 'remote-state', - limit: 10000, - threads: cdpList?.threads.filter((thread)=>thread.location === 'remote') ?? [] - }, { - limit: 10000, - host, - modelProvider: options.modelProvider, - project: options.project, - remotes - }); - const offset = remoteOffset ?? 0; - if (remoteOffset !== null || remoteInventory.threads.length >= limit) { - const page = []; - for (const thread of remoteInventory.threads.slice(offset, offset + limit)){ - const row = (0, _payload_budget_js__rspack_import_6.eX)(thread); - if ((0, _payload_budget_js__rspack_import_6.sQ)({ - ...remoteInventory, - threads: [ - ...page, - row - ], - nextCursor: REMOTE_PAGE_CURSOR, - ...options.groupBy === 'host' ? { - groups: groupThreadsByHost([ - ...page, - row - ]) - } : {} - }) > 614400) { - if (!page.length) throw new Error('ChatGPT Desktop remote thread row exceeds the MCP result byte budget'); - break; - } - page.push(row); + appRows.push(...out.threads); + if (out.warnings) warnings.push(...out.warnings); + if (!out.nextCursor) { + appComplete = true; + break; } - const nextOffset = offset + page.length; - const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; - return { - ...remoteInventory, - threads: page, - limit, - nextCursor, - ...options.groupBy === 'host' ? { - groupBy: 'host', - groups: groupThreadsByHost(page) - } : {} - }; + if (seenCursors.has(out.nextCursor)) throw new Error('App-server list returned a repeated cursor'); + seenCursors.add(out.nextCursor); + appCursor = out.nextCursor; } + if (!appComplete) warnings.push('App-server inventory stopped after 400 pages'); + } catch (error) { + warnings.push(`App-server list failed: ${error instanceof Error ? error.message : String(error)}`); } - const remoteKeys = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); - const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; - const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); - let appList = null; - let appError; + const remotes = this.#listRemotes(); + let cdpList = null; try { - appList = await this.#fallbacks.listThreads({ - limit: appLimit, - cursor: options.cursor === APP_START_CURSOR ? undefined : options.cursor, - modelProviders + await this.#ensureCdp(); + cdpList = await this.#cdp.listThreads({ + limit: 200 }); } catch (error) { - appError = error; - } - let base = null; - if (appList && cdpList) base = mergeThreadLists(appList, cdpList); - else if (appList) base = appList; - else if (cdpList) base = cdpList; - else if (remotes.length) base = { - backend: 'remote-state', - limit, - threads: [] + if (isCdpFailure(error)) this.#cdpConnected = false; + else warnings.push(`CDP list failed: ${error instanceof Error ? error.message : String(error)}`); + } + if (!appRows.length && !cdpList && !remotes.length) { + throw new _errors_js__rspack_import_3.sO(warnings[0] ?? 'ChatGPT Desktop listThreads: CDP and app-server unreachable'); + } + const appList = { + backend: 'app-server', + limit: appRows.length, + threads: appRows }; - else if (cdpError) throw cdpError; - else if (appError) throw appError; - else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); - const result = finalizeThreadList(base, { - limit, - host, + const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const merged = finalizeThreadList({ + ...base, + threads: (0, _project_state_js__rspack_import_6.j)(base.threads) + }, { + limit: Number.MAX_SAFE_INTEGER, + host: normalizeHostFilter(options.host), modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - groupBy: options.groupBy, - remotes + remotes: (0, _project_state_js__rspack_import_6.j)(remotes) }); - const withCursor = host === 'all' || host === 'local' ? result : { - ...result, - nextCursor: null + const rows = [ + ...new Map(merged.threads.map((row)=>[ + (0, _thread_ids_js__rspack_import_7.nn)(row.threadId) ?? row.threadId, + row + ])).values() + ]; + rows.sort(compareDesktopThreads); + const fingerprint = (0, node_crypto__rspack_import_0.createHash)('sha256').update(JSON.stringify({ + filters, + port: this.#port, + rows: rows.map((row)=>[ + row.threadId, + row.updatedAt, + row.location, + row.hostId + ]) + })).digest('base64url'); + const snapshot = { + fingerprint, + port: this.#port, + filters, + createdAt: Date.now(), + rows, + backend: merged.backend, + warnings }; - return appError ? { - ...withCursor, - warnings: [ - `App-server list failed: ${appError instanceof Error ? appError.message : String(appError)}` - ] - } : withCursor; + for (const [key, value] of this.#listSnapshots){ + if (Date.now() - value.createdAt > 15 * 60000 || this.#listSnapshots.size >= 8) this.#listSnapshots.delete(key); + } + this.#listSnapshots.set(fingerprint, snapshot); + return snapshot; } async listHosts() { const remotes = this.#listRemotes(); @@ -11833,7 +12003,7 @@ var __webpack_modules__ = { } catch { localThreadCount = 0; } - const listHosts = this.#fallbacks.listHosts ?? _remote_threads_js__rspack_import_4.Kl; + const listHosts = this.#fallbacks.listHosts ?? _remote_threads_js__rspack_import_5.Kl; const fromState = listHosts(process.env, { localThreadCount }); @@ -11898,7 +12068,7 @@ var __webpack_modules__ = { let modelProvidersSource = 'thread/list-distinct'; const warnings = []; try { - const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_1.X; + const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_2.X; const discovered = await discover(); modelProviders = [ ...discovered.providers @@ -11919,14 +12089,35 @@ var __webpack_modules__ = { ...remotes.map((thread)=>thread.modelProvider).filter((value)=>Boolean(value)) ]) ].sort(); + let inventoryCounts = null; + try { + const filters = JSON.stringify({ + host: 'all', + modelProvider: null, + project: null, + groupBy: null + }); + const cached = [ + ...this.#listSnapshots.values() + ].find((snapshot)=>snapshot.port === this.#port && snapshot.filters === filters && Date.now() - snapshot.createdAt < 15 * 60000); + const inventory = cached ?? await this.#buildListSnapshot({}, filters); + inventoryCounts = new Map(); + for (const thread of inventory.rows){ + const hostId = thread.location === 'remote' ? thread.hostId ?? 'unknown-remote' : 'local'; + inventoryCounts.set(hostId, (inventoryCounts.get(hostId) ?? 0) + 1); + } + warnings.push(...inventory.warnings); + } catch (error) { + warnings.push(`Merged inventory count failed: ${error instanceof Error ? error.message : String(error)}`); + } return { hosts: withCounts.map((host)=>{ - const counted = host.hostId === 'local' ? { + const counted = { ...host, - threadCount: localThreadCount - } : host; + threadCount: inventoryCounts?.get(host.hostId) ?? (host.hostId === 'local' ? localThreadCount : host.threadCount) + }; if (!counted.hostName) return counted; - const name = (0, _payload_budget_js__rspack_import_6.aA)(counted.hostName); + const name = (0, _payload_budget_js__rspack_import_8.aA)(counted.hostName); return { ...counted, hostName: name.title, @@ -11953,20 +12144,22 @@ var __webpack_modules__ = { query: options.query, limit, cursor: options.cursor, - modelProviders, - project: options.project + modelProviders }); const cdpList = options.cursor ? null : await this.#tryCdpList({ limit }); const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; const appMatches = new Set(appList.threads.map((thread)=>thread.threadId)); - const withRemotes = finalizeThreadList(base, { + const withRemotes = finalizeThreadList({ + ...base, + threads: (0, _project_state_js__rspack_import_6.j)(base.threads) + }, { limit: 10000, host, modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - remotes: options.cursor ? [] : this.#listRemotes() + remotes: options.cursor ? [] : (0, _project_state_js__rspack_import_6.j)(this.#listRemotes()) }); const needle = options.query.trim().toLowerCase(); const filtered = { @@ -11997,7 +12190,7 @@ var __webpack_modules__ = { limit }, query: options.query, - threads: (cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) + threads: (0, _project_state_js__rspack_import_6.j)(cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) }; const result = finalizeThreadList(filtered, { limit, @@ -12005,7 +12198,7 @@ var __webpack_modules__ = { modelProvider: options.modelProvider?.trim() || undefined, project: options.project, groupBy: options.groupBy, - remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) + remotes: (0, _project_state_js__rspack_import_6.j)(remotes).filter((thread)=>threadMatchesQuery(thread, needle)) }); return { ...result, @@ -12018,7 +12211,7 @@ var __webpack_modules__ = { async readThread(options) { const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; - if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { + if ((0, _thread_ids_js__rspack_import_7.vr)(options.threadId)) { if (options.cursor) throw new Error('Temporary Desktop threads do not support read cursors'); await this.#ensureCdp(); return this.#cdp.readThread({ @@ -12035,7 +12228,7 @@ var __webpack_modules__ = { cursor: options.cursor }); } catch (appError) { - if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; + if (appError instanceof _errors_js__rspack_import_3.Rg) throw appError; if (options.cursor) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; @@ -12055,15 +12248,15 @@ var __webpack_modules__ = { } async sendMessage(options) { if (options.threadId) { - const remote = (0, _remote_threads_js__rspack_import_4.KI)(options.threadId); - if (remote) throw new _errors_js__rspack_import_2.Rg(options.threadId, remote.hostId, remote.hostName); + const remote = (0, _remote_threads_js__rspack_import_5.KI)(options.threadId); + if (remote) throw new _errors_js__rspack_import_3.Rg(options.threadId, remote.hostId, remote.hostName); } await this.#ensureCdp(); try { return await this.#cdp.sendMessage(options); } catch (error) { - if (!(error instanceof _errors_js__rspack_import_2.fw) || !options.unarchive || !options.threadId) throw error; - await (this.#fallbacks.unarchiveThread ?? _app_server_fallback_js__rspack_import_1.qL)(options.threadId); + if (!(error instanceof _errors_js__rspack_import_3.fw) || !options.unarchive || !options.threadId) throw error; + await (this.#fallbacks.unarchiveThread ?? _app_server_fallback_js__rspack_import_2.qL)(options.threadId); return this.#cdp.sendMessage({ ...options, unarchive: false @@ -12075,8 +12268,8 @@ var __webpack_modules__ = { return this.#cdp.waitForReply(options); } async openThread(threadId, options) { - const remote = (0, _remote_threads_js__rspack_import_4.KI)(threadId); - if (remote) throw new _errors_js__rspack_import_2.Rg(threadId, remote.hostId, remote.hostName); + const remote = (0, _remote_threads_js__rspack_import_5.KI)(threadId); + if (remote) throw new _errors_js__rspack_import_3.Rg(threadId, remote.hostId, remote.hostName); await this.#ensureCdp(); return this.#cdp.openThread(threadId, options); } @@ -12105,7 +12298,7 @@ var __webpack_modules__ = { await this.#cdp.close(); } #listRemotes() { - const list = this.#fallbacks.listRemoteThreads ?? _remote_threads_js__rspack_import_4.Hx; + const list = this.#fallbacks.listRemoteThreads ?? _remote_threads_js__rspack_import_5.Hx; try { return list(); } catch { @@ -12134,7 +12327,7 @@ var __webpack_modules__ = { await this.#ensureCdp(); return await this.#cdp.listThreads(options); } catch (error) { - if (isCdpFailure(error) || error instanceof _errors_js__rspack_import_2.EH) { + if (isCdpFailure(error) || error instanceof _errors_js__rspack_import_3.EH) { if (isCdpFailure(error)) this.#cdpConnected = false; return null; } @@ -12145,11 +12338,11 @@ var __webpack_modules__ = { function mergeThreadLists(appList, cdpList) { const cdpByKey = new Map(); for (const thread of cdpList.threads){ - const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId; cdpByKey.set(key, thread); } const merged = appList.threads.map((thread)=>{ - const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId; const cdp = cdpByKey.get(key); const withLocal = { ...thread, @@ -12171,7 +12364,7 @@ var __webpack_modules__ = { }; }); for (const thread of cdpList.threads){ - if (merged.some((row)=>(0, _thread_ids_js__rspack_import_5.LV)(row.threadId, thread.threadId))) continue; + if (merged.some((row)=>(0, _thread_ids_js__rspack_import_7.LV)(row.threadId, thread.threadId))) continue; merged.push(thread); } return { @@ -12186,11 +12379,11 @@ var __webpack_modules__ = { } function finalizeThreadList(base, { limit, host = 'all', modelProvider, project, groupBy, remotes }) { const remoteById = new Map(remotes.map((thread)=>[ - (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId, + (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId, thread ])); const locals = base.threads.map((thread)=>{ - const remote = remoteById.get((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId); + const remote = remoteById.get((0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId); if (remote) { return { ...thread, @@ -12207,12 +12400,12 @@ var __webpack_modules__ = { hostName: location === 'remote' ? thread.hostName ?? null : null }; }); - const localKeys = new Set(locals.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + const localKeys = new Set(locals.map((thread)=>(0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId)); const merged = [ ...locals ]; for (const remote of remotes){ - const key = (0, _thread_ids_js__rspack_import_5.nn)(remote.threadId) ?? remote.threadId; + const key = (0, _thread_ids_js__rspack_import_7.nn)(remote.threadId) ?? remote.threadId; if (localKeys.has(key)) continue; merged.push({ ...remote, @@ -12220,6 +12413,7 @@ var __webpack_modules__ = { hostId: remote.hostId ?? null, hostName: remote.hostName ?? null }); + localKeys.add(key); } if (remotes.length) merged.sort((a, b)=>Number(b.location === 'remote') - Number(a.location === 'remote')); const filtered = merged.filter((thread)=>{ @@ -12228,7 +12422,7 @@ var __webpack_modules__ = { if (!projectMatches(thread, project)) return false; return true; }); - const limited = filtered.slice(0, limit).map(_payload_budget_js__rspack_import_6.eX); + const limited = filtered.slice(0, limit).map(_payload_budget_js__rspack_import_8.eX); const result = { backend: remotes.length ? base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' : base.backend === 'app-server' ? 'app-server+remote-state' : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend : base.backend, limit, @@ -12256,6 +12450,14 @@ var __webpack_modules__ = { } return result; } + function compareDesktopThreads(a, b) { + const timestamp = (row)=>{ + const value = row.updatedAt ?? row.createdAt; + if (typeof value !== 'number' || !Number.isFinite(value)) return Number.NEGATIVE_INFINITY; + return value < 100000000000 ? value * 1000 : value; + }; + return timestamp(b) - timestamp(a) || a.threadId.localeCompare(b.threadId); + } function groupThreadsByHost(threads) { const groups = new Map(); for (const thread of threads){ @@ -12323,8 +12525,8 @@ var __webpack_modules__ = { ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); } function isCdpFailure(error) { - if (error instanceof _errors_js__rspack_import_2.sO) return true; - if (error instanceof _errors_js__rspack_import_2.EH) return false; + if (error instanceof _errors_js__rspack_import_3.sO) return true; + if (error instanceof _errors_js__rspack_import_3.EH) return false; if (error && typeof error === 'object' && 'code' in error) { const code = String(error.code); return code === 'CDP_UNREACHABLE' || code === 'CDP_HOST_REJECTED'; @@ -12498,6 +12700,102 @@ var __webpack_modules__ = { sQ: ()=>serializedBytes }); }, + "./src/core/chatgpt-desktop/project-state.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + function findLocalProject(nameOrId, env = process.env) { + const state = (0, _codex_remote_control_js__rspack_import_0.IT)(env); + if (!state) return null; + for (const value of Object.values(record(stateValue(state, 'local-projects')) ?? {})){ + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.name !== 'string') continue; + if (row.id !== nameOrId && row.name.toLowerCase() !== nameOrId.toLowerCase()) continue; + return { + id: row.id, + label: row.name, + rootPaths: (Array.isArray(row.rootPaths) ? row.rootPaths : []).filter((path)=>typeof path === 'string' && Boolean(path)) + }; + } + return null; + } + function record(value) { + return value && typeof value === 'object' && !Array.isArray(value) ? value : null; + } + function stateValue(state, key) { + for (const source of (0, _codex_remote_control_js__rspack_import_0.xr)(state))if (key in source) return source[key]; + return undefined; + } + function pathWithin(path, root) { + const normalized = root.replace(/\/+$/u, ''); + return path === normalized || path.startsWith(`${normalized}/`); + } + function resolveThreadProjects(threads, env = process.env) { + const state = (0, _codex_remote_control_js__rspack_import_0.IT)(env); + if (!state) return [ + ...threads + ]; + const localProjects = Object.values(record(stateValue(state, 'local-projects')) ?? {}).flatMap((value)=>{ + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.name !== 'string') return []; + return (Array.isArray(row.rootPaths) ? row.rootPaths : []).filter((path)=>typeof path === 'string' && Boolean(path)).map((rootPath)=>({ + id: row.id, + label: row.name, + rootPath + })); + }); + const remoteProjects = (Array.isArray(stateValue(state, 'remote-projects')) ? stateValue(state, 'remote-projects') : []).flatMap((value)=>{ + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.label !== 'string' || typeof row.remotePath !== 'string' || typeof row.hostId !== 'string') return []; + return [ + { + id: row.id, + label: row.label, + rootPath: row.remotePath, + hostId: row.hostId + } + ]; + }); + const assignments = record(stateValue(state, 'thread-project-assignments')) ?? {}; + const hints = record(stateValue(state, 'thread-workspace-root-hints')) ?? {}; + const projectless = new Set(Array.isArray(stateValue(state, 'projectless-thread-ids')) ? stateValue(state, 'projectless-thread-ids') : []); + return threads.map((thread)=>{ + const bare = (0, _thread_ids_js__rspack_import_1.nn)(thread.threadId) ?? thread.threadId; + const assignment = record(assignments[bare]); + const remote = thread.location === 'remote'; + const projects = remote ? remoteProjects.filter((project)=>project.hostId === thread.hostId) : localProjects; + let project = assignment && typeof assignment.projectId === 'string' ? projects.find((entry)=>entry.id === assignment.projectId) : undefined; + if (!project && !projectless.has(bare) && thread.projectId) { + project = projects.find((entry)=>entry.id === thread.projectId); + } + if (!project && !assignment && !projectless.has(bare)) { + const path = typeof hints[bare] === 'string' ? hints[bare] : typeof thread.cwd === 'string' ? thread.cwd : null; + if (path) project = projects.filter((entry)=>pathWithin(path, entry.rootPath)).sort((a, b)=>b.rootPath.length - a.rootPath.length)[0]; + } + if (project) return { + ...thread, + project: project.label, + projectId: project.id, + projectRootPath: project.rootPath + }; + if (projectless.has(bare)) return { + ...thread, + project: null, + projectId: null + }; + if (remote && typeof thread.project === 'string' && thread.project.startsWith('/')) { + return { + ...thread, + project: null + }; + } + return thread; + }); + } + __webpack_require__.d(__webpack_exports__, { + j: ()=>resolveThreadProjects, + q: ()=>findLocalProject + }); + }, "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index b154c89..8a2d927 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8099,69 +8099,96 @@ var __webpack_modules__ = { let fetchLimit = Math.min(limit, 25); if (cursor?.startsWith(LIST_PAGE_PREFIX)) { const state = (0, _payload_budget_js__rspack_import_4.i3)(LIST_PAGE_PREFIX, cursor); - if (!Number.isSafeInteger(state.skip) || state.skip < 1 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || state.cursor !== null && typeof state.cursor !== 'string') { + if (!Number.isSafeInteger(state.skip) || state.skip < 0 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || state.cursor !== null && typeof state.cursor !== 'string') { throw new Error('Invalid ChatGPT Desktop list page cursor'); } sourceCursor = state.cursor ?? undefined; skip = state.skip; fetchLimit = state.fetchLimit; } - const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit: fetchLimit, - cursor: sourceCursor, - modelProviders - }); - if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); const base = { backend: 'app-server', limit, modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; const threads = []; - let consumed = skip; - for (const raw of out.threads.slice(skip)){ - if (threads.length >= limit) break; - let row = (0, _payload_budget_js__rspack_import_4.eX)(mapListedThread(raw)); - const probe = { - ...base, - threads: [ - ...threads, - row - ], - nextCursor: LIST_PAGE_PREFIX, - exitCode: 0 - }; - if ((0, _payload_budget_js__rspack_import_4.sQ)(probe) > 614400) { - if (threads.length) break; - row = (0, _payload_budget_js__rspack_import_4.MH)(row); - if ((0, _payload_budget_js__rspack_import_4.sQ)({ + const seen = new Set(); + for(let page = 0; page < 400; page++){ + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit: fetchLimit, + cursor: sourceCursor, + modelProviders + }); + if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); + for(let index = skip; index < out.threads.length; index++){ + let row = (0, _payload_budget_js__rspack_import_4.eX)(mapListedThread(out.threads[index])); + const probe = { ...base, threads: [ + ...threads, row ], nextCursor: LIST_PAGE_PREFIX, exitCode: 0 - }) > 614400) { - throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + }; + if ((0, _payload_budget_js__rspack_import_4.sQ)(probe) > 614400) { + if (threads.length) return { + ...base, + threads, + nextCursor: (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { + cursor: sourceCursor ?? null, + skip: index, + fetchLimit + }), + warnings: [ + 'List page stopped at the MCP byte budget; continue with nextCursor' + ] + }; + row = (0, _payload_budget_js__rspack_import_4.MH)(row); + if ((0, _payload_budget_js__rspack_import_4.sQ)({ + ...base, + threads: [ + row + ], + nextCursor: LIST_PAGE_PREFIX, + exitCode: 0 + }) > 614400) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + threads.push(row); + if (threads.length >= limit) { + const nextCursor = index + 1 < out.threads.length ? (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { + cursor: sourceCursor ?? null, + skip: index + 1, + fetchLimit + }) : out.nextCursor ?? null; + return { + ...base, + threads, + nextCursor + }; } } - threads.push(row); - consumed++; + if (out.nextCursor == null) return { + ...base, + threads, + nextCursor: null + }; + if (typeof out.nextCursor !== 'string' || !out.nextCursor || seen.has(out.nextCursor)) { + throw new Error('ChatGPT Desktop list returned an invalid or repeated cursor'); + } + seen.add(out.nextCursor); + sourceCursor = out.nextCursor; + skip = 0; } - const nextCursor = consumed < out.threads.length ? (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { - cursor: sourceCursor ?? null, - skip: consumed, - fetchLimit - }) : out.nextCursor ?? null; return { ...base, threads, - nextCursor, - ...consumed < out.threads.length ? { - warnings: [ - 'List page stopped at the MCP byte budget; continue with nextCursor' - ] - } : {} + nextCursor: sourceCursor, + warnings: [ + 'List stopped after 400 app-server pages; continue with nextCursor' + ] }; } async function appServerSearchThreads({ query, limit = 50, cursor, modelProviders = [], project }) { @@ -8760,13 +8787,15 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); - var _cdp_session_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); - var _cdp_dom_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); - var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); - var _loopback_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _cdp_session_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); + var _cdp_dom_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); + var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _loopback_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _project_state_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/project-state.ts"); class CdpChatGptDesktopAdapter { - #port = (0, _loopback_js__rspack_import_4.L0)(); + #port = (0, _loopback_js__rspack_import_5.L0)(); #session = null; #version = null; #pageSessionId = null; @@ -8774,8 +8803,8 @@ var __webpack_modules__ = { #submittedTurn = null; async connect({ port }) { await this.close(); - this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); - const session = new _cdp_session_js__rspack_import_1.a(this.#port); + this.#port = (0, _loopback_js__rspack_import_5.L0)(process.env, port); + const session = new _cdp_session_js__rspack_import_2.a(this.#port); try { this.#version = await session.connect(); this.#session = session; @@ -8789,11 +8818,11 @@ var __webpack_modules__ = { async listTargets() { const session = this.#requireSession(); const result = await session.send('Target.getTargets'); - return (0, _cdp_dom_js__rspack_import_2.Mr)(result.targetInfos ?? []); + return (0, _cdp_dom_js__rspack_import_3.Mr)(result.targetInfos ?? []); } async listThreads({ limit = 50 } = {}) { const sessionId = await this.#ensurePageSession(); - const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + const threads = await (0, _cdp_dom_js__rspack_import_3.AY)(this.#requireSession(), sessionId, { limit }); return { @@ -8805,7 +8834,7 @@ var __webpack_modules__ = { async readThread({ threadId, limit = 100, full = false, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); await this.#openAndWait(sessionId, threadId, openTimeoutMs); - const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + const turns = await (0, _cdp_dom_js__rspack_import_3.JU)(this.#requireSession(), sessionId, { limit, full, threadId @@ -8826,26 +8855,27 @@ var __webpack_modules__ = { if (threadId) { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } else { - await (0, _cdp_dom_js__rspack_import_2.s0)(this.#requireSession(), sessionId, { - project - }); - await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { - timeoutMs: openTimeoutMs, - threadId: 'new' + const localProject = project ? (0, _project_state_js__rspack_import_6.q)(project) : null; + if (localProject && !localProject.rootPaths.some((path)=>(0, node_fs__rspack_import_0.existsSync)(path))) { + throw new _errors_js__rspack_import_1.Kn(localProject.label, `none of its configured workspace roots exists: ${localProject.rootPaths.map((path)=>JSON.stringify(path)).join(', ') || '(none)'}. Update the Desktop project root before sending.`); + } + await (0, _cdp_dom_js__rspack_import_3.s0)(this.#requireSession(), sessionId, { + project: localProject?.label ?? project, + projectId: localProject?.id }); - const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + const threads = await (0, _cdp_dom_js__rspack_import_3.AY)(this.#requireSession(), sessionId, { limit: 20 }); - const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); + const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_3.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_3.hA)); if (temp) temporaryThreadId = temp.threadId; } - const before = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); - const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + const before = await (0, _cdp_dom_js__rspack_import_3.YX)(this.#requireSession(), sessionId); + const { sentVia } = await (0, _cdp_dom_js__rspack_import_3.lh)(this.#requireSession(), sessionId, text); let conversationId; - if (startedNew || threadId && (0, _thread_ids_js__rspack_import_3.vr)(threadId)) { + if (startedNew || threadId && (0, _thread_ids_js__rspack_import_4.vr)(threadId)) { const resolveMs = Math.min(openTimeoutMs, 60000); try { - conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { + conversationId = await (0, _cdp_dom_js__rspack_import_3.z9)(this.#requireSession(), sessionId, { timeoutMs: resolveMs }); } catch (error) { @@ -8855,7 +8885,7 @@ var __webpack_modules__ = { }); } } - const durable = (0, _cdp_dom_js__rspack_import_2.X8)(conversationId, threadId); + const durable = (0, _cdp_dom_js__rspack_import_3.X8)(conversationId, threadId); if (!durable) { throw new Error('ChatGPT Desktop send accepted but no durable conversation id was available; ' + 'refusing to return a local:client-new-thread:* id as threadId'); } @@ -8866,7 +8896,7 @@ var __webpack_modules__ = { return { threadId: durable, temporaryThreadId, - conversationId: conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, + conversationId: conversationId || (0, _thread_ids_js__rspack_import_4.nn)(durable) || durable, project, backend: 'cdp', experimental: false, @@ -8878,30 +8908,30 @@ var __webpack_modules__ = { async waitForReply({ threadId, timeoutMs = 120000 }) { const deadline = Date.now() + timeoutMs; const sessionId = await this.#ensurePageSession(); - const expectedId = threadId && threadId !== 'new' ? (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? undefined : this.#submittedTurn ? (0, _thread_ids_js__rspack_import_3.nn)(this.#submittedTurn.threadId) ?? undefined : undefined; - if (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) && threadId !== 'new') { + const expectedId = threadId && threadId !== 'new' ? (0, _thread_ids_js__rspack_import_4.nn)(threadId) ?? undefined : this.#submittedTurn ? (0, _thread_ids_js__rspack_import_4.nn)(this.#submittedTurn.threadId) ?? undefined : undefined; + if (threadId && !(0, _thread_ids_js__rspack_import_4.vr)(threadId) && threadId !== 'new') { await this.#openAndWait(sessionId, threadId, Math.min(timeoutMs, 90000)); } try { - const done = await (0, _cdp_dom_js__rspack_import_2.FG)(this.#requireSession(), sessionId, { + const done = await (0, _cdp_dom_js__rspack_import_3.FG)(this.#requireSession(), sessionId, { timeoutMs: Math.max(0, deadline - Date.now()), expectedConversationId: expectedId, - baselineTurnKey: this.#submittedTurn && (!threadId || (0, _thread_ids_js__rspack_import_3.BS)(threadId) === this.#submittedTurn.threadId) ? this.#submittedTurn.turnKey : undefined + baselineTurnKey: this.#submittedTurn && (!threadId || (0, _thread_ids_js__rspack_import_4.BS)(threadId) === this.#submittedTurn.threadId) ? this.#submittedTurn.turnKey : undefined }); - const durable = (0, _cdp_dom_js__rspack_import_2.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_3.BS)(done.conversationId) : null); + const durable = (0, _cdp_dom_js__rspack_import_3.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_4.BS)(done.conversationId) : null); if (!durable) { throw new Error('ChatGPT Desktop reply finished without a durable conversation id on ' + '[data-response-annotation-conversation]'); } return { threadId: durable, - conversationId: done.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, + conversationId: done.conversationId || (0, _thread_ids_js__rspack_import_4.nn)(durable) || durable, reply: done.reply, backend: 'cdp', experimental: false, delivery: 'replied' }; } catch (error) { - if (!(error instanceof _cdp_dom_js__rspack_import_2.aw)) throw error; + if (!(error instanceof _cdp_dom_js__rspack_import_3.aw)) throw error; return { threadId: threadId ?? 'unknown', reply: '', @@ -8916,7 +8946,7 @@ var __webpack_modules__ = { try { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } catch (error) { - if (error instanceof _errors_js__rspack_import_0.fw) return { + if (error instanceof _errors_js__rspack_import_1.fw) return { threadId, backend: 'cdp', archived: true @@ -8930,15 +8960,15 @@ var __webpack_modules__ = { } async status() { try { - const version = this.#version ?? await _cdp_session_js__rspack_import_1.a.fetchVersion(this.#port); + const version = this.#version ?? await _cdp_session_js__rspack_import_2.a.fetchVersion(this.#port); let targetCount; let mainWindowTargetId; if (this.#session && !this.#session.closed) { const targets = await this.listTargets(); targetCount = targets.length; - mainWindowTargetId = (0, _cdp_dom_js__rspack_import_2.C2)(targets)?.targetId ?? null; + mainWindowTargetId = (0, _cdp_dom_js__rspack_import_3.C2)(targets)?.targetId ?? null; } else { - const list = await _cdp_session_js__rspack_import_1.a.fetchJsonList(this.#port); + const list = await _cdp_session_js__rspack_import_2.a.fetchJsonList(this.#port); targetCount = list.length; } return { @@ -8971,17 +9001,17 @@ var __webpack_modules__ = { this.#session = null; } async #openAndWait(sessionId, threadId, openTimeoutMs) { - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { + await (0, _cdp_dom_js__rspack_import_3.Kl)(this.#requireSession(), sessionId, threadId); + await (0, _cdp_dom_js__rspack_import_3.Zx)(this.#requireSession(), sessionId, { timeoutMs: openTimeoutMs, threadId }); } async #attachMainWindow() { const targets = await this.listTargets(); - const main = (0, _cdp_dom_js__rspack_import_2.C2)(targets); + const main = (0, _cdp_dom_js__rspack_import_3.C2)(targets); if (!main) { - throw new _errors_js__rspack_import_0.sO(`No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`); + throw new _errors_js__rspack_import_1.sO(`No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`); } const attached = await this.#requireSession().send('Target.attachToTarget', { targetId: main.targetId, @@ -8994,13 +9024,13 @@ var __webpack_modules__ = { this.#requireSession(); if (!this.#pageSessionId) await this.#attachMainWindow(); if (!this.#pageSessionId) { - throw new _errors_js__rspack_import_0.sO('Failed to attach to ChatGPT Desktop main window'); + throw new _errors_js__rspack_import_1.sO('Failed to attach to ChatGPT Desktop main window'); } return this.#pageSessionId; } #requireSession() { if (!this.#session || this.#session.closed) { - throw new _errors_js__rspack_import_0.sO('Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.'); + throw new _errors_js__rspack_import_1.sO('Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.'); } return this.#session; } @@ -9191,17 +9221,18 @@ var __webpack_modules__ = { return { ok: false, error: 'router-not-found' }; })()`; } - function startNewChatExpression(project) { + function startNewChatExpression(project, projectId) { const projectSel = project ? newChatInProjectSelector(project) : null; return `(() => { const projectSel = ${JSON.stringify(projectSel)}; if (projectSel) { - const preferred = document.querySelector(projectSel); + const preferred = ${projectId ? `document.querySelector('[data-app-action-sidebar-project-id=${JSON.stringify(projectId)}]')?.querySelector(projectSel) ||` : ''} document.querySelector(projectSel); if (preferred) { - const row = preferred.closest('.group') || preferred.parentElement; + const row = preferred.closest('[data-app-action-sidebar-project-row]') || preferred.parentElement; row?.scrollIntoView({ block: 'center' }); const rowBox = row?.getBoundingClientRect(); return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)}, + disabled: preferred.disabled || preferred.getAttribute('aria-disabled') === 'true', hoverX: rowBox?.left + rowBox?.width / 2, hoverY: rowBox?.top + rowBox?.height / 2 }; } return { ok: false, error: 'project-not-found' }; @@ -9213,15 +9244,40 @@ var __webpack_modules__ = { return { ok: true, via: 'fallback' }; })()`; } - function projectButtonBoxExpression(project) { + function projectButtonBoxExpression(project, projectId) { return `(() => { - const button = document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); + const button = ${projectId ? `document.querySelector('[data-app-action-sidebar-project-id=${JSON.stringify(projectId)}]')?.querySelector(${JSON.stringify(newChatInProjectSelector(project))}) ||` : ''} document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); if (!button) return null; const box = button.getBoundingClientRect(); return { x: box.left + box.width / 2, y: box.top + box.height / 2, - visible: box.width > 0 && box.height > 0 && getComputedStyle(button.parentElement).opacity !== '0' }; + disabled: button.disabled || button.getAttribute('aria-disabled') === 'true', + visible: box.width > 0 && box.height > 0 && box.x >= 0 && box.y >= 0 + && box.x < innerWidth && box.y < innerHeight && getComputedStyle(button.parentElement).opacity !== '0' }; })()`; } + function newChatViewExpression(project) { + return `(() => { + const root = window.__codexRoot?._internalRoot?.current; + const queue = [root]; let scanned = 0; let path = ''; + while (queue.length && scanned++ < 10000) { + const fiber = queue.shift(); if (!fiber) continue; + const router = fiber.memoizedProps?.router; + if (router?.navigate && router?.state?.location) { path = router.state.location.pathname; break; } + if (fiber.child) queue.push(fiber.child); + if (fiber.sibling) queue.push(fiber.sibling); + } + const composer = !!document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + const scope = document.querySelector('[data-composer-navigation-target="workspace-project"]')?.getAttribute('aria-label') || ''; + const expected = ${JSON.stringify(project ? `Change project: ${project}` : '')}; + return { ready: path === '/' && composer && (expected ? scope === expected : (!scope || scope === 'Choose project')), path, composer, scope }; + })()`; + } + const CLEAR_NEW_CHAT_PROJECT_EXPRESSION = `(() => { + const button = document.querySelector('[data-clear-project-button="true"]'); + if (!button || button.disabled) return false; + button.click(); + return true; +})()`; const LOADING_TASK_GONE_EXPRESSION = `(() => { const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); @@ -9407,14 +9463,15 @@ var __webpack_modules__ = { } throw new Error(loadingGone ? `ChatGPT Desktop timed out waiting for conversation ${JSON.stringify(threadId)}; displayed conversation ${JSON.stringify(lastConversationId)} after ${timeoutMs}ms` : `ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); } - async function startNewChatInDom(session, sessionId, { project } = {}) { - const result = await session.evaluate(startNewChatExpression(project), { + async function startNewChatInDom(session, sessionId, { project, projectId, navigationTimeoutMs = 3000 } = {}) { + const result = await session.evaluate(startNewChatExpression(project, projectId), { sessionId }); if (!result?.ok) { throw new Error(project ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` : 'ChatGPT Desktop "New chat" button not found'); } if (result.via === 'project') { + if (result.disabled) throw new _errors_js__rspack_import_0.Kn(project, 'the Desktop project new-chat action is disabled; check its configured workspace root'); if (![ result.hoverX, result.hoverY @@ -9428,9 +9485,10 @@ var __webpack_modules__ = { }, { sessionId }); - const button = await session.evaluate(projectButtonBoxExpression(project), { + const button = await session.evaluate(projectButtonBoxExpression(project, projectId), { sessionId }); + if (button?.disabled) throw new _errors_js__rspack_import_0.Kn(project, 'the Desktop project new-chat action is disabled; check its configured workspace root'); if (!button?.visible || !Number.isFinite(button.x) || !Number.isFinite(button.y)) { throw new Error(`ChatGPT Desktop project button did not appear after hover for ${JSON.stringify(project)}`); } @@ -9460,9 +9518,28 @@ var __webpack_modules__ = { sessionId }); } - return { - via: result.via ?? 'unknown' + let observed = { + ready: false, + path: '', + composer: false, + scope: '' }; + const deadline = Date.now() + navigationTimeoutMs; + while(Date.now() < deadline){ + observed = await session.evaluate(newChatViewExpression(project), { + sessionId + }); + if (observed?.ready) return { + via: result.via ?? 'unknown' + }; + if (!project && observed?.path === '/' && observed?.composer && observed.scope.startsWith('Change project: ')) { + await session.evaluate(CLEAR_NEW_CHAT_PROJECT_EXPRESSION, { + sessionId + }); + } + await delay(100); + } + throw new _errors_js__rspack_import_0.XL(project, `route ${JSON.stringify(observed?.path)}, composer ${Boolean(observed?.composer)}, project ${JSON.stringify(observed?.scope)}`); } async function focusComposer(session, sessionId) { const focused = await session.evaluate(FOCUS_COMPOSER_EXPRESSION, { @@ -9887,6 +9964,24 @@ var __webpack_modules__ = { this.name = 'ComposerDraftError'; } } + class ProjectUnavailableError extends Error { + code = 'PROJECT_UNAVAILABLE'; + reason = 'project-unavailable'; + delivery = 'rejected'; + constructor(project, detail){ + super(`ChatGPT Desktop cannot start a chat in project ${JSON.stringify(project)}: ${detail}`); + this.name = 'ProjectUnavailableError'; + } + } + class NewChatNavigationError extends Error { + code = 'NEW_CHAT_NAVIGATION_FAILED'; + reason = 'new-chat-navigation-failed'; + delivery = 'rejected'; + constructor(project, observed){ + super(`ChatGPT Desktop new-chat action did not open ${project ? `project ${JSON.stringify(project)}` : 'a projectless chat'}; observed ${observed}`); + this.name = 'NewChatNavigationError'; + } + } class NotImplementedError extends Error { code = 'NOT_IMPLEMENTED'; delivery = 'rejected'; @@ -9916,7 +10011,9 @@ var __webpack_modules__ = { } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, + Kn: ()=>ProjectUnavailableError, Rg: ()=>_codex_remote_control_js__rspack_import_0.Rg, + XL: ()=>NewChatNavigationError, c$: ()=>CdpHostRejectedError, fw: ()=>ArchivedThreadError, oN: ()=>ComposerDraftError, @@ -9924,37 +10021,39 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/facade.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var _cdp_adapter_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-adapter.ts"); - var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); - var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); - var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); - var _remote_threads_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); - var _payload_budget_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); - var _thread_ids_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var node_crypto__rspack_import_0 = __webpack_require__("node:crypto"); + var _cdp_adapter_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-adapter.ts"); + var _app_server_fallback_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); + var _errors_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _loopback_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _remote_threads_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _project_state_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/project-state.ts"); + var _payload_budget_js__rspack_import_8 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); + var _thread_ids_js__rspack_import_7 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { - listThreads: _app_server_fallback_js__rspack_import_1.OI, - searchThreads: _app_server_fallback_js__rspack_import_1.aI, - readThread: _app_server_fallback_js__rspack_import_1.Jf, - unarchiveThread: _app_server_fallback_js__rspack_import_1.qL, - statusProbe: _app_server_fallback_js__rspack_import_1.dM, - listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, - listHosts: _remote_threads_js__rspack_import_4.Kl, - discoverModelProviders: _app_server_fallback_js__rspack_import_1.X + listThreads: _app_server_fallback_js__rspack_import_2.OI, + searchThreads: _app_server_fallback_js__rspack_import_2.aI, + readThread: _app_server_fallback_js__rspack_import_2.Jf, + unarchiveThread: _app_server_fallback_js__rspack_import_2.qL, + statusProbe: _app_server_fallback_js__rspack_import_2.dM, + listRemoteThreads: _remote_threads_js__rspack_import_5.Hx, + listHosts: _remote_threads_js__rspack_import_5.Kl, + discoverModelProviders: _app_server_fallback_js__rspack_import_2.X }; - const REMOTE_PAGE_CURSOR = 'desktop-remote-page:'; - const APP_START_CURSOR = 'desktop-app-start'; + const MERGED_LIST_CURSOR = 'desktop-merged-list-v1:'; class ChatGptDesktopFacade { #cdp; #port; #cdpConnected = false; #fallbacks; - constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)(), fallbacks = defaultFallbacks){ + #listSnapshots = new Map(); + constructor(cdp = new _cdp_adapter_js__rspack_import_1.a(), port = (0, _loopback_js__rspack_import_4.L0)(), fallbacks = defaultFallbacks){ this.#cdp = cdp; this.#port = port; this.#fallbacks = fallbacks; } async connect({ port }) { - this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); try { await this.#cdp.connect({ port: this.#port @@ -9971,124 +10070,195 @@ var __webpack_modules__ = { } async listThreads(options = {}) { const limit = options.limit ?? 50; + const filters = JSON.stringify({ + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || null, + project: options.project?.trim() || null, + groupBy: options.groupBy ?? null + }); + let snapshot; + let offset = 0; + if (options.cursor) { + const state = (0, _payload_budget_js__rspack_import_8.i3)(MERGED_LIST_CURSOR, options.cursor); + if (state.port !== this.#port || state.filters !== filters || !Number.isSafeInteger(state.offset) || state.offset < 1 || typeof state.fingerprint !== 'string') { + throw new Error('ChatGPT Desktop list cursor does not match the port or filters'); + } + offset = state.offset; + snapshot = this.#listSnapshots.get(state.fingerprint) ?? await this.#buildListSnapshot(options, filters); + if (snapshot.fingerprint !== state.fingerprint || snapshot.filters !== filters || snapshot.port !== this.#port) { + throw new Error('ChatGPT Desktop thread inventory changed; restart listing without a cursor'); + } + } else { + snapshot = await this.#buildListSnapshot(options, filters); + } + if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop list cursor is out of range'); const host = normalizeHostFilter(options.host); - const modelProviders = modelProvidersFromFilter(options.modelProvider); - const remoteOffset = options.cursor?.startsWith(REMOTE_PAGE_CURSOR) ? Number(options.cursor.slice(REMOTE_PAGE_CURSOR.length)) : null; - if (remoteOffset !== null && (!Number.isSafeInteger(remoteOffset) || remoteOffset < 1)) { - throw new Error('Invalid ChatGPT Desktop remote page cursor'); + const rows = []; + const base = { + backend: snapshot.backend, + limit, + host, + ...options.modelProvider?.trim() ? { + modelProvider: options.modelProvider.trim() + } : {}, + ...options.project ? { + project: options.project + } : {}, + ...options.groupBy === 'host' ? { + groupBy: 'host' + } : {} + }; + for (const source of snapshot.rows.slice(offset, offset + limit)){ + let row = source; + const candidate = [ + ...rows, + row + ]; + const probe = { + ...base, + threads: candidate, + nextCursor: MERGED_LIST_CURSOR, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost(candidate) + } : {}, + warnings: snapshot.warnings, + exitCode: 0 + }; + if ((0, _payload_budget_js__rspack_import_8.sQ)(probe) > 614400) { + if (rows.length) break; + row = (0, _payload_budget_js__rspack_import_8.MH)(row); + const minimal = [ + row + ]; + if ((0, _payload_budget_js__rspack_import_8.sQ)({ + ...base, + threads: minimal, + nextCursor: MERGED_LIST_CURSOR, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost(minimal) + } : {}, + warnings: snapshot.warnings, + exitCode: 0 + }) > 614400) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + rows.push(row); } - const inventoryPage = !options.cursor || remoteOffset !== null; - const remotes = inventoryPage ? this.#listRemotes() : []; - let cdpList = null; - let cdpError; + const nextOffset = offset + rows.length; + const nextCursor = nextOffset < snapshot.rows.length ? (0, _payload_budget_js__rspack_import_8.oI)(MERGED_LIST_CURSOR, { + fingerprint: snapshot.fingerprint, + offset: nextOffset, + port: this.#port, + filters + }) : null; + const warnings = [ + ...snapshot.warnings + ]; + if (rows.length < Math.min(limit, snapshot.rows.length - offset)) { + warnings.push('List page stopped at the MCP byte budget; continue with nextCursor'); + } + return { + ...base, + threads: rows, + nextCursor, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost(rows) + } : {}, + ...warnings.length ? { + warnings + } : {} + }; + } + async #buildListSnapshot(options, filters) { + const appRows = []; + const warnings = []; + let appCursor; + let appComplete = false; + const seenCursors = new Set(); + const modelProviders = modelProvidersFromFilter(options.modelProvider); try { - if (inventoryPage) { - await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads({ - limit: 200 + for(let page = 0; page < 400; page++){ + const out = await this.#fallbacks.listThreads({ + limit: 200, + cursor: appCursor, + modelProviders }); - } - } catch (error) { - if (isCdpFailure(error)) { - this.#cdpConnected = false; - } else { - cdpError = error; - } - } - if (inventoryPage && host !== 'local') { - const remoteInventory = finalizeThreadList({ - backend: cdpList?.backend ?? 'remote-state', - limit: 10000, - threads: cdpList?.threads.filter((thread)=>thread.location === 'remote') ?? [] - }, { - limit: 10000, - host, - modelProvider: options.modelProvider, - project: options.project, - remotes - }); - const offset = remoteOffset ?? 0; - if (remoteOffset !== null || remoteInventory.threads.length >= limit) { - const page = []; - for (const thread of remoteInventory.threads.slice(offset, offset + limit)){ - const row = (0, _payload_budget_js__rspack_import_6.eX)(thread); - if ((0, _payload_budget_js__rspack_import_6.sQ)({ - ...remoteInventory, - threads: [ - ...page, - row - ], - nextCursor: REMOTE_PAGE_CURSOR, - ...options.groupBy === 'host' ? { - groups: groupThreadsByHost([ - ...page, - row - ]) - } : {} - }) > 614400) { - if (!page.length) throw new Error('ChatGPT Desktop remote thread row exceeds the MCP result byte budget'); - break; - } - page.push(row); + appRows.push(...out.threads); + if (out.warnings) warnings.push(...out.warnings); + if (!out.nextCursor) { + appComplete = true; + break; } - const nextOffset = offset + page.length; - const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; - return { - ...remoteInventory, - threads: page, - limit, - nextCursor, - ...options.groupBy === 'host' ? { - groupBy: 'host', - groups: groupThreadsByHost(page) - } : {} - }; + if (seenCursors.has(out.nextCursor)) throw new Error('App-server list returned a repeated cursor'); + seenCursors.add(out.nextCursor); + appCursor = out.nextCursor; } + if (!appComplete) warnings.push('App-server inventory stopped after 400 pages'); + } catch (error) { + warnings.push(`App-server list failed: ${error instanceof Error ? error.message : String(error)}`); } - const remoteKeys = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); - const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; - const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); - let appList = null; - let appError; + const remotes = this.#listRemotes(); + let cdpList = null; try { - appList = await this.#fallbacks.listThreads({ - limit: appLimit, - cursor: options.cursor === APP_START_CURSOR ? undefined : options.cursor, - modelProviders + await this.#ensureCdp(); + cdpList = await this.#cdp.listThreads({ + limit: 200 }); } catch (error) { - appError = error; - } - let base = null; - if (appList && cdpList) base = mergeThreadLists(appList, cdpList); - else if (appList) base = appList; - else if (cdpList) base = cdpList; - else if (remotes.length) base = { - backend: 'remote-state', - limit, - threads: [] + if (isCdpFailure(error)) this.#cdpConnected = false; + else warnings.push(`CDP list failed: ${error instanceof Error ? error.message : String(error)}`); + } + if (!appRows.length && !cdpList && !remotes.length) { + throw new _errors_js__rspack_import_3.sO(warnings[0] ?? 'ChatGPT Desktop listThreads: CDP and app-server unreachable'); + } + const appList = { + backend: 'app-server', + limit: appRows.length, + threads: appRows }; - else if (cdpError) throw cdpError; - else if (appError) throw appError; - else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); - const result = finalizeThreadList(base, { - limit, - host, + const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const merged = finalizeThreadList({ + ...base, + threads: (0, _project_state_js__rspack_import_6.j)(base.threads) + }, { + limit: Number.MAX_SAFE_INTEGER, + host: normalizeHostFilter(options.host), modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - groupBy: options.groupBy, - remotes + remotes: (0, _project_state_js__rspack_import_6.j)(remotes) }); - const withCursor = host === 'all' || host === 'local' ? result : { - ...result, - nextCursor: null + const rows = [ + ...new Map(merged.threads.map((row)=>[ + (0, _thread_ids_js__rspack_import_7.nn)(row.threadId) ?? row.threadId, + row + ])).values() + ]; + rows.sort(compareDesktopThreads); + const fingerprint = (0, node_crypto__rspack_import_0.createHash)('sha256').update(JSON.stringify({ + filters, + port: this.#port, + rows: rows.map((row)=>[ + row.threadId, + row.updatedAt, + row.location, + row.hostId + ]) + })).digest('base64url'); + const snapshot = { + fingerprint, + port: this.#port, + filters, + createdAt: Date.now(), + rows, + backend: merged.backend, + warnings }; - return appError ? { - ...withCursor, - warnings: [ - `App-server list failed: ${appError instanceof Error ? appError.message : String(appError)}` - ] - } : withCursor; + for (const [key, value] of this.#listSnapshots){ + if (Date.now() - value.createdAt > 15 * 60000 || this.#listSnapshots.size >= 8) this.#listSnapshots.delete(key); + } + this.#listSnapshots.set(fingerprint, snapshot); + return snapshot; } async listHosts() { const remotes = this.#listRemotes(); @@ -10105,7 +10275,7 @@ var __webpack_modules__ = { } catch { localThreadCount = 0; } - const listHosts = this.#fallbacks.listHosts ?? _remote_threads_js__rspack_import_4.Kl; + const listHosts = this.#fallbacks.listHosts ?? _remote_threads_js__rspack_import_5.Kl; const fromState = listHosts(process.env, { localThreadCount }); @@ -10170,7 +10340,7 @@ var __webpack_modules__ = { let modelProvidersSource = 'thread/list-distinct'; const warnings = []; try { - const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_1.X; + const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_2.X; const discovered = await discover(); modelProviders = [ ...discovered.providers @@ -10191,14 +10361,35 @@ var __webpack_modules__ = { ...remotes.map((thread)=>thread.modelProvider).filter((value)=>Boolean(value)) ]) ].sort(); + let inventoryCounts = null; + try { + const filters = JSON.stringify({ + host: 'all', + modelProvider: null, + project: null, + groupBy: null + }); + const cached = [ + ...this.#listSnapshots.values() + ].find((snapshot)=>snapshot.port === this.#port && snapshot.filters === filters && Date.now() - snapshot.createdAt < 15 * 60000); + const inventory = cached ?? await this.#buildListSnapshot({}, filters); + inventoryCounts = new Map(); + for (const thread of inventory.rows){ + const hostId = thread.location === 'remote' ? thread.hostId ?? 'unknown-remote' : 'local'; + inventoryCounts.set(hostId, (inventoryCounts.get(hostId) ?? 0) + 1); + } + warnings.push(...inventory.warnings); + } catch (error) { + warnings.push(`Merged inventory count failed: ${error instanceof Error ? error.message : String(error)}`); + } return { hosts: withCounts.map((host)=>{ - const counted = host.hostId === 'local' ? { + const counted = { ...host, - threadCount: localThreadCount - } : host; + threadCount: inventoryCounts?.get(host.hostId) ?? (host.hostId === 'local' ? localThreadCount : host.threadCount) + }; if (!counted.hostName) return counted; - const name = (0, _payload_budget_js__rspack_import_6.aA)(counted.hostName); + const name = (0, _payload_budget_js__rspack_import_8.aA)(counted.hostName); return { ...counted, hostName: name.title, @@ -10225,20 +10416,22 @@ var __webpack_modules__ = { query: options.query, limit, cursor: options.cursor, - modelProviders, - project: options.project + modelProviders }); const cdpList = options.cursor ? null : await this.#tryCdpList({ limit }); const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; const appMatches = new Set(appList.threads.map((thread)=>thread.threadId)); - const withRemotes = finalizeThreadList(base, { + const withRemotes = finalizeThreadList({ + ...base, + threads: (0, _project_state_js__rspack_import_6.j)(base.threads) + }, { limit: 10000, host, modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - remotes: options.cursor ? [] : this.#listRemotes() + remotes: options.cursor ? [] : (0, _project_state_js__rspack_import_6.j)(this.#listRemotes()) }); const needle = options.query.trim().toLowerCase(); const filtered = { @@ -10269,7 +10462,7 @@ var __webpack_modules__ = { limit }, query: options.query, - threads: (cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) + threads: (0, _project_state_js__rspack_import_6.j)(cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) }; const result = finalizeThreadList(filtered, { limit, @@ -10277,7 +10470,7 @@ var __webpack_modules__ = { modelProvider: options.modelProvider?.trim() || undefined, project: options.project, groupBy: options.groupBy, - remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) + remotes: (0, _project_state_js__rspack_import_6.j)(remotes).filter((thread)=>threadMatchesQuery(thread, needle)) }); return { ...result, @@ -10290,7 +10483,7 @@ var __webpack_modules__ = { async readThread(options) { const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; - if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { + if ((0, _thread_ids_js__rspack_import_7.vr)(options.threadId)) { if (options.cursor) throw new Error('Temporary Desktop threads do not support read cursors'); await this.#ensureCdp(); return this.#cdp.readThread({ @@ -10307,7 +10500,7 @@ var __webpack_modules__ = { cursor: options.cursor }); } catch (appError) { - if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; + if (appError instanceof _errors_js__rspack_import_3.Rg) throw appError; if (options.cursor) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; @@ -10327,15 +10520,15 @@ var __webpack_modules__ = { } async sendMessage(options) { if (options.threadId) { - const remote = (0, _remote_threads_js__rspack_import_4.KI)(options.threadId); - if (remote) throw new _errors_js__rspack_import_2.Rg(options.threadId, remote.hostId, remote.hostName); + const remote = (0, _remote_threads_js__rspack_import_5.KI)(options.threadId); + if (remote) throw new _errors_js__rspack_import_3.Rg(options.threadId, remote.hostId, remote.hostName); } await this.#ensureCdp(); try { return await this.#cdp.sendMessage(options); } catch (error) { - if (!(error instanceof _errors_js__rspack_import_2.fw) || !options.unarchive || !options.threadId) throw error; - await (this.#fallbacks.unarchiveThread ?? _app_server_fallback_js__rspack_import_1.qL)(options.threadId); + if (!(error instanceof _errors_js__rspack_import_3.fw) || !options.unarchive || !options.threadId) throw error; + await (this.#fallbacks.unarchiveThread ?? _app_server_fallback_js__rspack_import_2.qL)(options.threadId); return this.#cdp.sendMessage({ ...options, unarchive: false @@ -10347,8 +10540,8 @@ var __webpack_modules__ = { return this.#cdp.waitForReply(options); } async openThread(threadId, options) { - const remote = (0, _remote_threads_js__rspack_import_4.KI)(threadId); - if (remote) throw new _errors_js__rspack_import_2.Rg(threadId, remote.hostId, remote.hostName); + const remote = (0, _remote_threads_js__rspack_import_5.KI)(threadId); + if (remote) throw new _errors_js__rspack_import_3.Rg(threadId, remote.hostId, remote.hostName); await this.#ensureCdp(); return this.#cdp.openThread(threadId, options); } @@ -10377,7 +10570,7 @@ var __webpack_modules__ = { await this.#cdp.close(); } #listRemotes() { - const list = this.#fallbacks.listRemoteThreads ?? _remote_threads_js__rspack_import_4.Hx; + const list = this.#fallbacks.listRemoteThreads ?? _remote_threads_js__rspack_import_5.Hx; try { return list(); } catch { @@ -10406,7 +10599,7 @@ var __webpack_modules__ = { await this.#ensureCdp(); return await this.#cdp.listThreads(options); } catch (error) { - if (isCdpFailure(error) || error instanceof _errors_js__rspack_import_2.EH) { + if (isCdpFailure(error) || error instanceof _errors_js__rspack_import_3.EH) { if (isCdpFailure(error)) this.#cdpConnected = false; return null; } @@ -10417,11 +10610,11 @@ var __webpack_modules__ = { function mergeThreadLists(appList, cdpList) { const cdpByKey = new Map(); for (const thread of cdpList.threads){ - const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId; cdpByKey.set(key, thread); } const merged = appList.threads.map((thread)=>{ - const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId; const cdp = cdpByKey.get(key); const withLocal = { ...thread, @@ -10443,7 +10636,7 @@ var __webpack_modules__ = { }; }); for (const thread of cdpList.threads){ - if (merged.some((row)=>(0, _thread_ids_js__rspack_import_5.LV)(row.threadId, thread.threadId))) continue; + if (merged.some((row)=>(0, _thread_ids_js__rspack_import_7.LV)(row.threadId, thread.threadId))) continue; merged.push(thread); } return { @@ -10458,11 +10651,11 @@ var __webpack_modules__ = { } function finalizeThreadList(base, { limit, host = 'all', modelProvider, project, groupBy, remotes }) { const remoteById = new Map(remotes.map((thread)=>[ - (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId, + (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId, thread ])); const locals = base.threads.map((thread)=>{ - const remote = remoteById.get((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId); + const remote = remoteById.get((0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId); if (remote) { return { ...thread, @@ -10479,12 +10672,12 @@ var __webpack_modules__ = { hostName: location === 'remote' ? thread.hostName ?? null : null }; }); - const localKeys = new Set(locals.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + const localKeys = new Set(locals.map((thread)=>(0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId)); const merged = [ ...locals ]; for (const remote of remotes){ - const key = (0, _thread_ids_js__rspack_import_5.nn)(remote.threadId) ?? remote.threadId; + const key = (0, _thread_ids_js__rspack_import_7.nn)(remote.threadId) ?? remote.threadId; if (localKeys.has(key)) continue; merged.push({ ...remote, @@ -10492,6 +10685,7 @@ var __webpack_modules__ = { hostId: remote.hostId ?? null, hostName: remote.hostName ?? null }); + localKeys.add(key); } if (remotes.length) merged.sort((a, b)=>Number(b.location === 'remote') - Number(a.location === 'remote')); const filtered = merged.filter((thread)=>{ @@ -10500,7 +10694,7 @@ var __webpack_modules__ = { if (!projectMatches(thread, project)) return false; return true; }); - const limited = filtered.slice(0, limit).map(_payload_budget_js__rspack_import_6.eX); + const limited = filtered.slice(0, limit).map(_payload_budget_js__rspack_import_8.eX); const result = { backend: remotes.length ? base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' : base.backend === 'app-server' ? 'app-server+remote-state' : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend : base.backend, limit, @@ -10528,6 +10722,14 @@ var __webpack_modules__ = { } return result; } + function compareDesktopThreads(a, b) { + const timestamp = (row)=>{ + const value = row.updatedAt ?? row.createdAt; + if (typeof value !== 'number' || !Number.isFinite(value)) return Number.NEGATIVE_INFINITY; + return value < 100000000000 ? value * 1000 : value; + }; + return timestamp(b) - timestamp(a) || a.threadId.localeCompare(b.threadId); + } function groupThreadsByHost(threads) { const groups = new Map(); for (const thread of threads){ @@ -10595,8 +10797,8 @@ var __webpack_modules__ = { ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); } function isCdpFailure(error) { - if (error instanceof _errors_js__rspack_import_2.sO) return true; - if (error instanceof _errors_js__rspack_import_2.EH) return false; + if (error instanceof _errors_js__rspack_import_3.sO) return true; + if (error instanceof _errors_js__rspack_import_3.EH) return false; if (error && typeof error === 'object' && 'code' in error) { const code = String(error.code); return code === 'CDP_UNREACHABLE' || code === 'CDP_HOST_REJECTED'; @@ -10770,6 +10972,102 @@ var __webpack_modules__ = { sQ: ()=>serializedBytes }); }, + "./src/core/chatgpt-desktop/project-state.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + function findLocalProject(nameOrId, env = process.env) { + const state = (0, _codex_remote_control_js__rspack_import_0.IT)(env); + if (!state) return null; + for (const value of Object.values(record(stateValue(state, 'local-projects')) ?? {})){ + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.name !== 'string') continue; + if (row.id !== nameOrId && row.name.toLowerCase() !== nameOrId.toLowerCase()) continue; + return { + id: row.id, + label: row.name, + rootPaths: (Array.isArray(row.rootPaths) ? row.rootPaths : []).filter((path)=>typeof path === 'string' && Boolean(path)) + }; + } + return null; + } + function record(value) { + return value && typeof value === 'object' && !Array.isArray(value) ? value : null; + } + function stateValue(state, key) { + for (const source of (0, _codex_remote_control_js__rspack_import_0.xr)(state))if (key in source) return source[key]; + return undefined; + } + function pathWithin(path, root) { + const normalized = root.replace(/\/+$/u, ''); + return path === normalized || path.startsWith(`${normalized}/`); + } + function resolveThreadProjects(threads, env = process.env) { + const state = (0, _codex_remote_control_js__rspack_import_0.IT)(env); + if (!state) return [ + ...threads + ]; + const localProjects = Object.values(record(stateValue(state, 'local-projects')) ?? {}).flatMap((value)=>{ + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.name !== 'string') return []; + return (Array.isArray(row.rootPaths) ? row.rootPaths : []).filter((path)=>typeof path === 'string' && Boolean(path)).map((rootPath)=>({ + id: row.id, + label: row.name, + rootPath + })); + }); + const remoteProjects = (Array.isArray(stateValue(state, 'remote-projects')) ? stateValue(state, 'remote-projects') : []).flatMap((value)=>{ + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.label !== 'string' || typeof row.remotePath !== 'string' || typeof row.hostId !== 'string') return []; + return [ + { + id: row.id, + label: row.label, + rootPath: row.remotePath, + hostId: row.hostId + } + ]; + }); + const assignments = record(stateValue(state, 'thread-project-assignments')) ?? {}; + const hints = record(stateValue(state, 'thread-workspace-root-hints')) ?? {}; + const projectless = new Set(Array.isArray(stateValue(state, 'projectless-thread-ids')) ? stateValue(state, 'projectless-thread-ids') : []); + return threads.map((thread)=>{ + const bare = (0, _thread_ids_js__rspack_import_1.nn)(thread.threadId) ?? thread.threadId; + const assignment = record(assignments[bare]); + const remote = thread.location === 'remote'; + const projects = remote ? remoteProjects.filter((project)=>project.hostId === thread.hostId) : localProjects; + let project = assignment && typeof assignment.projectId === 'string' ? projects.find((entry)=>entry.id === assignment.projectId) : undefined; + if (!project && !projectless.has(bare) && thread.projectId) { + project = projects.find((entry)=>entry.id === thread.projectId); + } + if (!project && !assignment && !projectless.has(bare)) { + const path = typeof hints[bare] === 'string' ? hints[bare] : typeof thread.cwd === 'string' ? thread.cwd : null; + if (path) project = projects.filter((entry)=>pathWithin(path, entry.rootPath)).sort((a, b)=>b.rootPath.length - a.rootPath.length)[0]; + } + if (project) return { + ...thread, + project: project.label, + projectId: project.id, + projectRootPath: project.rootPath + }; + if (projectless.has(bare)) return { + ...thread, + project: null, + projectId: null + }; + if (remote && typeof thread.project === 'string' && thread.project.startsWith('/')) { + return { + ...thread, + project: null + }; + } + return thread; + }); + } + __webpack_require__.d(__webpack_exports__, { + j: ()=>resolveThreadProjects, + q: ()=>findLocalProject + }); + }, "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); @@ -12190,7 +12488,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List Desktop threads, then pass nextCursor as cursor until null. Pages may stop early at the MCP byte budget. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', + description: 'List one sorted Desktop inventory without duplicate rows. Pass nextCursor as cursor with unchanged filters until null; pages fill limit unless the MCP byte budget binds. A changed/expired inventory cursor requires restarting. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or Desktop project label/projectId; projectRootPath identifies the resolved workspace. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', annotations: { readOnlyHint: true }, @@ -12443,7 +12741,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop send', - description: 'Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.', + description: 'Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. The empty view and project scope are checked before typing. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. PROJECT_UNAVAILABLE identifies a disabled project action or missing configured root; NEW_CHAT_NAVIGATION_FAILED reports an unchanged view promptly. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.', annotations: { readOnlyHint: false }, @@ -28887,7 +29185,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": true }, - "description": "List Desktop threads, then pass nextCursor as cursor until null. Pages may stop early at the MCP byte budget. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.", + "description": "List one sorted Desktop inventory without duplicate rows. Pass nextCursor as cursor with unchanged filters until null; pages fill limit unless the MCP byte budget binds. A changed/expired inventory cursor requires restarting. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or Desktop project label/projectId; projectRootPath identifies the resolved workspace. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -29080,7 +29378,7 @@ const routes = Object.freeze({ "annotations": { "readOnlyHint": false }, - "description": "Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.", + "description": "Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. The empty view and project scope are checked before typing. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. PROJECT_UNAVAILABLE identifies a disabled project action or missing configured root; NEW_CHAT_NAVIGATION_FAILED reports an unchanged view promptly. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.", "inputJsonSchema": { "additionalProperties": false, "properties": { diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index c3452a6..cd09ae7 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -6507,69 +6507,96 @@ var __webpack_modules__ = { let fetchLimit = Math.min(limit, 25); if (cursor?.startsWith(LIST_PAGE_PREFIX)) { const state = (0, _payload_budget_js__rspack_import_4.i3)(LIST_PAGE_PREFIX, cursor); - if (!Number.isSafeInteger(state.skip) || state.skip < 1 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || state.cursor !== null && typeof state.cursor !== 'string') { + if (!Number.isSafeInteger(state.skip) || state.skip < 0 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || state.cursor !== null && typeof state.cursor !== 'string') { throw new Error('Invalid ChatGPT Desktop list page cursor'); } sourceCursor = state.cursor ?? undefined; skip = state.skip; fetchLimit = state.fetchLimit; } - const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ - limit: fetchLimit, - cursor: sourceCursor, - modelProviders - }); - if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); const base = { backend: 'app-server', limit, modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined }; const threads = []; - let consumed = skip; - for (const raw of out.threads.slice(skip)){ - if (threads.length >= limit) break; - let row = (0, _payload_budget_js__rspack_import_4.eX)(mapListedThread(raw)); - const probe = { - ...base, - threads: [ - ...threads, - row - ], - nextCursor: LIST_PAGE_PREFIX, - exitCode: 0 - }; - if ((0, _payload_budget_js__rspack_import_4.sQ)(probe) > 614400) { - if (threads.length) break; - row = (0, _payload_budget_js__rspack_import_4.MH)(row); - if ((0, _payload_budget_js__rspack_import_4.sQ)({ + const seen = new Set(); + for(let page = 0; page < 400; page++){ + const out = await (0, _codex_bridge_js__rspack_import_0.X$)({ + limit: fetchLimit, + cursor: sourceCursor, + modelProviders + }); + if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); + for(let index = skip; index < out.threads.length; index++){ + let row = (0, _payload_budget_js__rspack_import_4.eX)(mapListedThread(out.threads[index])); + const probe = { ...base, threads: [ + ...threads, row ], nextCursor: LIST_PAGE_PREFIX, exitCode: 0 - }) > 614400) { - throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + }; + if ((0, _payload_budget_js__rspack_import_4.sQ)(probe) > 614400) { + if (threads.length) return { + ...base, + threads, + nextCursor: (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { + cursor: sourceCursor ?? null, + skip: index, + fetchLimit + }), + warnings: [ + 'List page stopped at the MCP byte budget; continue with nextCursor' + ] + }; + row = (0, _payload_budget_js__rspack_import_4.MH)(row); + if ((0, _payload_budget_js__rspack_import_4.sQ)({ + ...base, + threads: [ + row + ], + nextCursor: LIST_PAGE_PREFIX, + exitCode: 0 + }) > 614400) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + threads.push(row); + if (threads.length >= limit) { + const nextCursor = index + 1 < out.threads.length ? (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { + cursor: sourceCursor ?? null, + skip: index + 1, + fetchLimit + }) : out.nextCursor ?? null; + return { + ...base, + threads, + nextCursor + }; } } - threads.push(row); - consumed++; + if (out.nextCursor == null) return { + ...base, + threads, + nextCursor: null + }; + if (typeof out.nextCursor !== 'string' || !out.nextCursor || seen.has(out.nextCursor)) { + throw new Error('ChatGPT Desktop list returned an invalid or repeated cursor'); + } + seen.add(out.nextCursor); + sourceCursor = out.nextCursor; + skip = 0; } - const nextCursor = consumed < out.threads.length ? (0, _payload_budget_js__rspack_import_4.oI)(LIST_PAGE_PREFIX, { - cursor: sourceCursor ?? null, - skip: consumed, - fetchLimit - }) : out.nextCursor ?? null; return { ...base, threads, - nextCursor, - ...consumed < out.threads.length ? { - warnings: [ - 'List page stopped at the MCP byte budget; continue with nextCursor' - ] - } : {} + nextCursor: sourceCursor, + warnings: [ + 'List stopped after 400 app-server pages; continue with nextCursor' + ] }; } async function appServerSearchThreads({ query, limit = 50, cursor, modelProviders = [], project }) { @@ -7168,13 +7195,15 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/cdp-adapter.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var _errors_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); - var _cdp_session_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); - var _cdp_dom_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); - var _thread_ids_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); - var _loopback_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var node_fs__rspack_import_0 = __webpack_require__("node:fs"); + var _errors_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _cdp_session_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/cdp-session.ts"); + var _cdp_dom_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/cdp-dom.ts"); + var _thread_ids_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var _loopback_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _project_state_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/project-state.ts"); class CdpChatGptDesktopAdapter { - #port = (0, _loopback_js__rspack_import_4.L0)(); + #port = (0, _loopback_js__rspack_import_5.L0)(); #session = null; #version = null; #pageSessionId = null; @@ -7182,8 +7211,8 @@ var __webpack_modules__ = { #submittedTurn = null; async connect({ port }) { await this.close(); - this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); - const session = new _cdp_session_js__rspack_import_1.a(this.#port); + this.#port = (0, _loopback_js__rspack_import_5.L0)(process.env, port); + const session = new _cdp_session_js__rspack_import_2.a(this.#port); try { this.#version = await session.connect(); this.#session = session; @@ -7197,11 +7226,11 @@ var __webpack_modules__ = { async listTargets() { const session = this.#requireSession(); const result = await session.send('Target.getTargets'); - return (0, _cdp_dom_js__rspack_import_2.Mr)(result.targetInfos ?? []); + return (0, _cdp_dom_js__rspack_import_3.Mr)(result.targetInfos ?? []); } async listThreads({ limit = 50 } = {}) { const sessionId = await this.#ensurePageSession(); - const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + const threads = await (0, _cdp_dom_js__rspack_import_3.AY)(this.#requireSession(), sessionId, { limit }); return { @@ -7213,7 +7242,7 @@ var __webpack_modules__ = { async readThread({ threadId, limit = 100, full = false, openTimeoutMs = 90000 }) { const sessionId = await this.#ensurePageSession(); await this.#openAndWait(sessionId, threadId, openTimeoutMs); - const turns = await (0, _cdp_dom_js__rspack_import_2.JU)(this.#requireSession(), sessionId, { + const turns = await (0, _cdp_dom_js__rspack_import_3.JU)(this.#requireSession(), sessionId, { limit, full, threadId @@ -7234,26 +7263,27 @@ var __webpack_modules__ = { if (threadId) { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } else { - await (0, _cdp_dom_js__rspack_import_2.s0)(this.#requireSession(), sessionId, { - project - }); - await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { - timeoutMs: openTimeoutMs, - threadId: 'new' + const localProject = project ? (0, _project_state_js__rspack_import_6.q)(project) : null; + if (localProject && !localProject.rootPaths.some((path)=>(0, node_fs__rspack_import_0.existsSync)(path))) { + throw new _errors_js__rspack_import_1.Kn(localProject.label, `none of its configured workspace roots exists: ${localProject.rootPaths.map((path)=>JSON.stringify(path)).join(', ') || '(none)'}. Update the Desktop project root before sending.`); + } + await (0, _cdp_dom_js__rspack_import_3.s0)(this.#requireSession(), sessionId, { + project: localProject?.label ?? project, + projectId: localProject?.id }); - const threads = await (0, _cdp_dom_js__rspack_import_2.AY)(this.#requireSession(), sessionId, { + const threads = await (0, _cdp_dom_js__rspack_import_3.AY)(this.#requireSession(), sessionId, { limit: 20 }); - const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_2.hA)); + const temp = threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_3.hA) && t.selected) ?? threads.find((t)=>t.threadId.startsWith(_cdp_dom_js__rspack_import_3.hA)); if (temp) temporaryThreadId = temp.threadId; } - const before = await (0, _cdp_dom_js__rspack_import_2.YX)(this.#requireSession(), sessionId); - const { sentVia } = await (0, _cdp_dom_js__rspack_import_2.lh)(this.#requireSession(), sessionId, text); + const before = await (0, _cdp_dom_js__rspack_import_3.YX)(this.#requireSession(), sessionId); + const { sentVia } = await (0, _cdp_dom_js__rspack_import_3.lh)(this.#requireSession(), sessionId, text); let conversationId; - if (startedNew || threadId && (0, _thread_ids_js__rspack_import_3.vr)(threadId)) { + if (startedNew || threadId && (0, _thread_ids_js__rspack_import_4.vr)(threadId)) { const resolveMs = Math.min(openTimeoutMs, 60000); try { - conversationId = await (0, _cdp_dom_js__rspack_import_2.z9)(this.#requireSession(), sessionId, { + conversationId = await (0, _cdp_dom_js__rspack_import_3.z9)(this.#requireSession(), sessionId, { timeoutMs: resolveMs }); } catch (error) { @@ -7263,7 +7293,7 @@ var __webpack_modules__ = { }); } } - const durable = (0, _cdp_dom_js__rspack_import_2.X8)(conversationId, threadId); + const durable = (0, _cdp_dom_js__rspack_import_3.X8)(conversationId, threadId); if (!durable) { throw new Error('ChatGPT Desktop send accepted but no durable conversation id was available; ' + 'refusing to return a local:client-new-thread:* id as threadId'); } @@ -7274,7 +7304,7 @@ var __webpack_modules__ = { return { threadId: durable, temporaryThreadId, - conversationId: conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, + conversationId: conversationId || (0, _thread_ids_js__rspack_import_4.nn)(durable) || durable, project, backend: 'cdp', experimental: false, @@ -7286,30 +7316,30 @@ var __webpack_modules__ = { async waitForReply({ threadId, timeoutMs = 120000 }) { const deadline = Date.now() + timeoutMs; const sessionId = await this.#ensurePageSession(); - const expectedId = threadId && threadId !== 'new' ? (0, _thread_ids_js__rspack_import_3.nn)(threadId) ?? undefined : this.#submittedTurn ? (0, _thread_ids_js__rspack_import_3.nn)(this.#submittedTurn.threadId) ?? undefined : undefined; - if (threadId && !(0, _thread_ids_js__rspack_import_3.vr)(threadId) && threadId !== 'new') { + const expectedId = threadId && threadId !== 'new' ? (0, _thread_ids_js__rspack_import_4.nn)(threadId) ?? undefined : this.#submittedTurn ? (0, _thread_ids_js__rspack_import_4.nn)(this.#submittedTurn.threadId) ?? undefined : undefined; + if (threadId && !(0, _thread_ids_js__rspack_import_4.vr)(threadId) && threadId !== 'new') { await this.#openAndWait(sessionId, threadId, Math.min(timeoutMs, 90000)); } try { - const done = await (0, _cdp_dom_js__rspack_import_2.FG)(this.#requireSession(), sessionId, { + const done = await (0, _cdp_dom_js__rspack_import_3.FG)(this.#requireSession(), sessionId, { timeoutMs: Math.max(0, deadline - Date.now()), expectedConversationId: expectedId, - baselineTurnKey: this.#submittedTurn && (!threadId || (0, _thread_ids_js__rspack_import_3.BS)(threadId) === this.#submittedTurn.threadId) ? this.#submittedTurn.turnKey : undefined + baselineTurnKey: this.#submittedTurn && (!threadId || (0, _thread_ids_js__rspack_import_4.BS)(threadId) === this.#submittedTurn.threadId) ? this.#submittedTurn.turnKey : undefined }); - const durable = (0, _cdp_dom_js__rspack_import_2.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_3.BS)(done.conversationId) : null); + const durable = (0, _cdp_dom_js__rspack_import_3.X8)(done.conversationId, threadId) ?? (done.conversationId ? (0, _thread_ids_js__rspack_import_4.BS)(done.conversationId) : null); if (!durable) { throw new Error('ChatGPT Desktop reply finished without a durable conversation id on ' + '[data-response-annotation-conversation]'); } return { threadId: durable, - conversationId: done.conversationId || (0, _thread_ids_js__rspack_import_3.nn)(durable) || durable, + conversationId: done.conversationId || (0, _thread_ids_js__rspack_import_4.nn)(durable) || durable, reply: done.reply, backend: 'cdp', experimental: false, delivery: 'replied' }; } catch (error) { - if (!(error instanceof _cdp_dom_js__rspack_import_2.aw)) throw error; + if (!(error instanceof _cdp_dom_js__rspack_import_3.aw)) throw error; return { threadId: threadId ?? 'unknown', reply: '', @@ -7324,7 +7354,7 @@ var __webpack_modules__ = { try { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } catch (error) { - if (error instanceof _errors_js__rspack_import_0.fw) return { + if (error instanceof _errors_js__rspack_import_1.fw) return { threadId, backend: 'cdp', archived: true @@ -7338,15 +7368,15 @@ var __webpack_modules__ = { } async status() { try { - const version = this.#version ?? await _cdp_session_js__rspack_import_1.a.fetchVersion(this.#port); + const version = this.#version ?? await _cdp_session_js__rspack_import_2.a.fetchVersion(this.#port); let targetCount; let mainWindowTargetId; if (this.#session && !this.#session.closed) { const targets = await this.listTargets(); targetCount = targets.length; - mainWindowTargetId = (0, _cdp_dom_js__rspack_import_2.C2)(targets)?.targetId ?? null; + mainWindowTargetId = (0, _cdp_dom_js__rspack_import_3.C2)(targets)?.targetId ?? null; } else { - const list = await _cdp_session_js__rspack_import_1.a.fetchJsonList(this.#port); + const list = await _cdp_session_js__rspack_import_2.a.fetchJsonList(this.#port); targetCount = list.length; } return { @@ -7379,17 +7409,17 @@ var __webpack_modules__ = { this.#session = null; } async #openAndWait(sessionId, threadId, openTimeoutMs) { - await (0, _cdp_dom_js__rspack_import_2.Kl)(this.#requireSession(), sessionId, threadId); - await (0, _cdp_dom_js__rspack_import_2.Zx)(this.#requireSession(), sessionId, { + await (0, _cdp_dom_js__rspack_import_3.Kl)(this.#requireSession(), sessionId, threadId); + await (0, _cdp_dom_js__rspack_import_3.Zx)(this.#requireSession(), sessionId, { timeoutMs: openTimeoutMs, threadId }); } async #attachMainWindow() { const targets = await this.listTargets(); - const main = (0, _cdp_dom_js__rspack_import_2.C2)(targets); + const main = (0, _cdp_dom_js__rspack_import_3.C2)(targets); if (!main) { - throw new _errors_js__rspack_import_0.sO(`No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`); + throw new _errors_js__rspack_import_1.sO(`No ChatGPT Desktop main window target with url ${JSON.stringify('app://-/index.html')}`); } const attached = await this.#requireSession().send('Target.attachToTarget', { targetId: main.targetId, @@ -7402,13 +7432,13 @@ var __webpack_modules__ = { this.#requireSession(); if (!this.#pageSessionId) await this.#attachMainWindow(); if (!this.#pageSessionId) { - throw new _errors_js__rspack_import_0.sO('Failed to attach to ChatGPT Desktop main window'); + throw new _errors_js__rspack_import_1.sO('Failed to attach to ChatGPT Desktop main window'); } return this.#pageSessionId; } #requireSession() { if (!this.#session || this.#session.closed) { - throw new _errors_js__rspack_import_0.sO('Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.'); + throw new _errors_js__rspack_import_1.sO('Not connected to ChatGPT Desktop CDP. Call connect({ port }) after relaunching with --remote-debugging-port.'); } return this.#session; } @@ -7599,17 +7629,18 @@ var __webpack_modules__ = { return { ok: false, error: 'router-not-found' }; })()`; } - function startNewChatExpression(project) { + function startNewChatExpression(project, projectId) { const projectSel = project ? newChatInProjectSelector(project) : null; return `(() => { const projectSel = ${JSON.stringify(projectSel)}; if (projectSel) { - const preferred = document.querySelector(projectSel); + const preferred = ${projectId ? `document.querySelector('[data-app-action-sidebar-project-id=${JSON.stringify(projectId)}]')?.querySelector(projectSel) ||` : ''} document.querySelector(projectSel); if (preferred) { - const row = preferred.closest('.group') || preferred.parentElement; + const row = preferred.closest('[data-app-action-sidebar-project-row]') || preferred.parentElement; row?.scrollIntoView({ block: 'center' }); const rowBox = row?.getBoundingClientRect(); return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)}, + disabled: preferred.disabled || preferred.getAttribute('aria-disabled') === 'true', hoverX: rowBox?.left + rowBox?.width / 2, hoverY: rowBox?.top + rowBox?.height / 2 }; } return { ok: false, error: 'project-not-found' }; @@ -7621,15 +7652,40 @@ var __webpack_modules__ = { return { ok: true, via: 'fallback' }; })()`; } - function projectButtonBoxExpression(project) { + function projectButtonBoxExpression(project, projectId) { return `(() => { - const button = document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); + const button = ${projectId ? `document.querySelector('[data-app-action-sidebar-project-id=${JSON.stringify(projectId)}]')?.querySelector(${JSON.stringify(newChatInProjectSelector(project))}) ||` : ''} document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); if (!button) return null; const box = button.getBoundingClientRect(); return { x: box.left + box.width / 2, y: box.top + box.height / 2, - visible: box.width > 0 && box.height > 0 && getComputedStyle(button.parentElement).opacity !== '0' }; + disabled: button.disabled || button.getAttribute('aria-disabled') === 'true', + visible: box.width > 0 && box.height > 0 && box.x >= 0 && box.y >= 0 + && box.x < innerWidth && box.y < innerHeight && getComputedStyle(button.parentElement).opacity !== '0' }; + })()`; + } + function newChatViewExpression(project) { + return `(() => { + const root = window.__codexRoot?._internalRoot?.current; + const queue = [root]; let scanned = 0; let path = ''; + while (queue.length && scanned++ < 10000) { + const fiber = queue.shift(); if (!fiber) continue; + const router = fiber.memoizedProps?.router; + if (router?.navigate && router?.state?.location) { path = router.state.location.pathname; break; } + if (fiber.child) queue.push(fiber.child); + if (fiber.sibling) queue.push(fiber.sibling); + } + const composer = !!document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + const scope = document.querySelector('[data-composer-navigation-target="workspace-project"]')?.getAttribute('aria-label') || ''; + const expected = ${JSON.stringify(project ? `Change project: ${project}` : '')}; + return { ready: path === '/' && composer && (expected ? scope === expected : (!scope || scope === 'Choose project')), path, composer, scope }; })()`; } + const CLEAR_NEW_CHAT_PROJECT_EXPRESSION = `(() => { + const button = document.querySelector('[data-clear-project-button="true"]'); + if (!button || button.disabled) return false; + button.click(); + return true; +})()`; const LOADING_TASK_GONE_EXPRESSION = `(() => { const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); @@ -7815,14 +7871,15 @@ var __webpack_modules__ = { } throw new Error(loadingGone ? `ChatGPT Desktop timed out waiting for conversation ${JSON.stringify(threadId)}; displayed conversation ${JSON.stringify(lastConversationId)} after ${timeoutMs}ms` : `ChatGPT Desktop thread still showing ${JSON.stringify(LOADING_TASK_TEXT)} after ${timeoutMs}ms`); } - async function startNewChatInDom(session, sessionId, { project } = {}) { - const result = await session.evaluate(startNewChatExpression(project), { + async function startNewChatInDom(session, sessionId, { project, projectId, navigationTimeoutMs = 3000 } = {}) { + const result = await session.evaluate(startNewChatExpression(project, projectId), { sessionId }); if (!result?.ok) { throw new Error(project ? `ChatGPT Desktop new-chat button not found for project ${JSON.stringify(project)}` : 'ChatGPT Desktop "New chat" button not found'); } if (result.via === 'project') { + if (result.disabled) throw new _errors_js__rspack_import_0.Kn(project, 'the Desktop project new-chat action is disabled; check its configured workspace root'); if (![ result.hoverX, result.hoverY @@ -7836,9 +7893,10 @@ var __webpack_modules__ = { }, { sessionId }); - const button = await session.evaluate(projectButtonBoxExpression(project), { + const button = await session.evaluate(projectButtonBoxExpression(project, projectId), { sessionId }); + if (button?.disabled) throw new _errors_js__rspack_import_0.Kn(project, 'the Desktop project new-chat action is disabled; check its configured workspace root'); if (!button?.visible || !Number.isFinite(button.x) || !Number.isFinite(button.y)) { throw new Error(`ChatGPT Desktop project button did not appear after hover for ${JSON.stringify(project)}`); } @@ -7868,9 +7926,28 @@ var __webpack_modules__ = { sessionId }); } - return { - via: result.via ?? 'unknown' + let observed = { + ready: false, + path: '', + composer: false, + scope: '' }; + const deadline = Date.now() + navigationTimeoutMs; + while(Date.now() < deadline){ + observed = await session.evaluate(newChatViewExpression(project), { + sessionId + }); + if (observed?.ready) return { + via: result.via ?? 'unknown' + }; + if (!project && observed?.path === '/' && observed?.composer && observed.scope.startsWith('Change project: ')) { + await session.evaluate(CLEAR_NEW_CHAT_PROJECT_EXPRESSION, { + sessionId + }); + } + await delay(100); + } + throw new _errors_js__rspack_import_0.XL(project, `route ${JSON.stringify(observed?.path)}, composer ${Boolean(observed?.composer)}, project ${JSON.stringify(observed?.scope)}`); } async function focusComposer(session, sessionId) { const focused = await session.evaluate(FOCUS_COMPOSER_EXPRESSION, { @@ -8295,6 +8372,24 @@ var __webpack_modules__ = { this.name = 'ComposerDraftError'; } } + class ProjectUnavailableError extends Error { + code = 'PROJECT_UNAVAILABLE'; + reason = 'project-unavailable'; + delivery = 'rejected'; + constructor(project, detail){ + super(`ChatGPT Desktop cannot start a chat in project ${JSON.stringify(project)}: ${detail}`); + this.name = 'ProjectUnavailableError'; + } + } + class NewChatNavigationError extends Error { + code = 'NEW_CHAT_NAVIGATION_FAILED'; + reason = 'new-chat-navigation-failed'; + delivery = 'rejected'; + constructor(project, observed){ + super(`ChatGPT Desktop new-chat action did not open ${project ? `project ${JSON.stringify(project)}` : 'a projectless chat'}; observed ${observed}`); + this.name = 'NewChatNavigationError'; + } + } class NotImplementedError extends Error { code = 'NOT_IMPLEMENTED'; delivery = 'rejected'; @@ -8324,7 +8419,9 @@ var __webpack_modules__ = { } __webpack_require__.d(__webpack_exports__, { EH: ()=>NotImplementedError, + Kn: ()=>ProjectUnavailableError, Rg: ()=>_codex_remote_control_js__rspack_import_0.Rg, + XL: ()=>NewChatNavigationError, c$: ()=>CdpHostRejectedError, fw: ()=>ArchivedThreadError, oN: ()=>ComposerDraftError, @@ -8332,37 +8429,39 @@ var __webpack_modules__ = { }); }, "./src/core/chatgpt-desktop/facade.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { - var _cdp_adapter_js__rspack_import_0 = __webpack_require__("./src/core/chatgpt-desktop/cdp-adapter.ts"); - var _app_server_fallback_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); - var _errors_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); - var _loopback_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); - var _remote_threads_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); - var _payload_budget_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); - var _thread_ids_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + var node_crypto__rspack_import_0 = __webpack_require__("node:crypto"); + var _cdp_adapter_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/cdp-adapter.ts"); + var _app_server_fallback_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/app-server-fallback.ts"); + var _errors_js__rspack_import_3 = __webpack_require__("./src/core/chatgpt-desktop/errors.ts"); + var _loopback_js__rspack_import_4 = __webpack_require__("./src/core/chatgpt-desktop/loopback.ts"); + var _remote_threads_js__rspack_import_5 = __webpack_require__("./src/core/chatgpt-desktop/remote-threads.ts"); + var _project_state_js__rspack_import_6 = __webpack_require__("./src/core/chatgpt-desktop/project-state.ts"); + var _payload_budget_js__rspack_import_8 = __webpack_require__("./src/core/chatgpt-desktop/payload-budget.ts"); + var _thread_ids_js__rspack_import_7 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); const defaultFallbacks = { - listThreads: _app_server_fallback_js__rspack_import_1.OI, - searchThreads: _app_server_fallback_js__rspack_import_1.aI, - readThread: _app_server_fallback_js__rspack_import_1.Jf, - unarchiveThread: _app_server_fallback_js__rspack_import_1.qL, - statusProbe: _app_server_fallback_js__rspack_import_1.dM, - listRemoteThreads: _remote_threads_js__rspack_import_4.Hx, - listHosts: _remote_threads_js__rspack_import_4.Kl, - discoverModelProviders: _app_server_fallback_js__rspack_import_1.X - }; - const REMOTE_PAGE_CURSOR = 'desktop-remote-page:'; - const APP_START_CURSOR = 'desktop-app-start'; + listThreads: _app_server_fallback_js__rspack_import_2.OI, + searchThreads: _app_server_fallback_js__rspack_import_2.aI, + readThread: _app_server_fallback_js__rspack_import_2.Jf, + unarchiveThread: _app_server_fallback_js__rspack_import_2.qL, + statusProbe: _app_server_fallback_js__rspack_import_2.dM, + listRemoteThreads: _remote_threads_js__rspack_import_5.Hx, + listHosts: _remote_threads_js__rspack_import_5.Kl, + discoverModelProviders: _app_server_fallback_js__rspack_import_2.X + }; + const MERGED_LIST_CURSOR = 'desktop-merged-list-v1:'; class ChatGptDesktopFacade { #cdp; #port; #cdpConnected = false; #fallbacks; - constructor(cdp = new _cdp_adapter_js__rspack_import_0.a(), port = (0, _loopback_js__rspack_import_3.L0)(), fallbacks = defaultFallbacks){ + #listSnapshots = new Map(); + constructor(cdp = new _cdp_adapter_js__rspack_import_1.a(), port = (0, _loopback_js__rspack_import_4.L0)(), fallbacks = defaultFallbacks){ this.#cdp = cdp; this.#port = port; this.#fallbacks = fallbacks; } async connect({ port }) { - this.#port = (0, _loopback_js__rspack_import_3.L0)(process.env, port); + this.#port = (0, _loopback_js__rspack_import_4.L0)(process.env, port); try { await this.#cdp.connect({ port: this.#port @@ -8379,124 +8478,195 @@ var __webpack_modules__ = { } async listThreads(options = {}) { const limit = options.limit ?? 50; + const filters = JSON.stringify({ + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || null, + project: options.project?.trim() || null, + groupBy: options.groupBy ?? null + }); + let snapshot; + let offset = 0; + if (options.cursor) { + const state = (0, _payload_budget_js__rspack_import_8.i3)(MERGED_LIST_CURSOR, options.cursor); + if (state.port !== this.#port || state.filters !== filters || !Number.isSafeInteger(state.offset) || state.offset < 1 || typeof state.fingerprint !== 'string') { + throw new Error('ChatGPT Desktop list cursor does not match the port or filters'); + } + offset = state.offset; + snapshot = this.#listSnapshots.get(state.fingerprint) ?? await this.#buildListSnapshot(options, filters); + if (snapshot.fingerprint !== state.fingerprint || snapshot.filters !== filters || snapshot.port !== this.#port) { + throw new Error('ChatGPT Desktop thread inventory changed; restart listing without a cursor'); + } + } else { + snapshot = await this.#buildListSnapshot(options, filters); + } + if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop list cursor is out of range'); const host = normalizeHostFilter(options.host); - const modelProviders = modelProvidersFromFilter(options.modelProvider); - const remoteOffset = options.cursor?.startsWith(REMOTE_PAGE_CURSOR) ? Number(options.cursor.slice(REMOTE_PAGE_CURSOR.length)) : null; - if (remoteOffset !== null && (!Number.isSafeInteger(remoteOffset) || remoteOffset < 1)) { - throw new Error('Invalid ChatGPT Desktop remote page cursor'); + const rows = []; + const base = { + backend: snapshot.backend, + limit, + host, + ...options.modelProvider?.trim() ? { + modelProvider: options.modelProvider.trim() + } : {}, + ...options.project ? { + project: options.project + } : {}, + ...options.groupBy === 'host' ? { + groupBy: 'host' + } : {} + }; + for (const source of snapshot.rows.slice(offset, offset + limit)){ + let row = source; + const candidate = [ + ...rows, + row + ]; + const probe = { + ...base, + threads: candidate, + nextCursor: MERGED_LIST_CURSOR, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost(candidate) + } : {}, + warnings: snapshot.warnings, + exitCode: 0 + }; + if ((0, _payload_budget_js__rspack_import_8.sQ)(probe) > 614400) { + if (rows.length) break; + row = (0, _payload_budget_js__rspack_import_8.MH)(row); + const minimal = [ + row + ]; + if ((0, _payload_budget_js__rspack_import_8.sQ)({ + ...base, + threads: minimal, + nextCursor: MERGED_LIST_CURSOR, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost(minimal) + } : {}, + warnings: snapshot.warnings, + exitCode: 0 + }) > 614400) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + rows.push(row); } - const inventoryPage = !options.cursor || remoteOffset !== null; - const remotes = inventoryPage ? this.#listRemotes() : []; - let cdpList = null; - let cdpError; + const nextOffset = offset + rows.length; + const nextCursor = nextOffset < snapshot.rows.length ? (0, _payload_budget_js__rspack_import_8.oI)(MERGED_LIST_CURSOR, { + fingerprint: snapshot.fingerprint, + offset: nextOffset, + port: this.#port, + filters + }) : null; + const warnings = [ + ...snapshot.warnings + ]; + if (rows.length < Math.min(limit, snapshot.rows.length - offset)) { + warnings.push('List page stopped at the MCP byte budget; continue with nextCursor'); + } + return { + ...base, + threads: rows, + nextCursor, + ...options.groupBy === 'host' ? { + groups: groupThreadsByHost(rows) + } : {}, + ...warnings.length ? { + warnings + } : {} + }; + } + async #buildListSnapshot(options, filters) { + const appRows = []; + const warnings = []; + let appCursor; + let appComplete = false; + const seenCursors = new Set(); + const modelProviders = modelProvidersFromFilter(options.modelProvider); try { - if (inventoryPage) { - await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads({ - limit: 200 + for(let page = 0; page < 400; page++){ + const out = await this.#fallbacks.listThreads({ + limit: 200, + cursor: appCursor, + modelProviders }); - } - } catch (error) { - if (isCdpFailure(error)) { - this.#cdpConnected = false; - } else { - cdpError = error; - } - } - if (inventoryPage && host !== 'local') { - const remoteInventory = finalizeThreadList({ - backend: cdpList?.backend ?? 'remote-state', - limit: 10000, - threads: cdpList?.threads.filter((thread)=>thread.location === 'remote') ?? [] - }, { - limit: 10000, - host, - modelProvider: options.modelProvider, - project: options.project, - remotes - }); - const offset = remoteOffset ?? 0; - if (remoteOffset !== null || remoteInventory.threads.length >= limit) { - const page = []; - for (const thread of remoteInventory.threads.slice(offset, offset + limit)){ - const row = (0, _payload_budget_js__rspack_import_6.eX)(thread); - if ((0, _payload_budget_js__rspack_import_6.sQ)({ - ...remoteInventory, - threads: [ - ...page, - row - ], - nextCursor: REMOTE_PAGE_CURSOR, - ...options.groupBy === 'host' ? { - groups: groupThreadsByHost([ - ...page, - row - ]) - } : {} - }) > 614400) { - if (!page.length) throw new Error('ChatGPT Desktop remote thread row exceeds the MCP result byte budget'); - break; - } - page.push(row); + appRows.push(...out.threads); + if (out.warnings) warnings.push(...out.warnings); + if (!out.nextCursor) { + appComplete = true; + break; } - const nextOffset = offset + page.length; - const nextCursor = nextOffset < remoteInventory.threads.length ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; - return { - ...remoteInventory, - threads: page, - limit, - nextCursor, - ...options.groupBy === 'host' ? { - groupBy: 'host', - groups: groupThreadsByHost(page) - } : {} - }; + if (seenCursors.has(out.nextCursor)) throw new Error('App-server list returned a repeated cursor'); + seenCursors.add(out.nextCursor); + appCursor = out.nextCursor; } + if (!appComplete) warnings.push('App-server inventory stopped after 400 pages'); + } catch (error) { + warnings.push(`App-server list failed: ${error instanceof Error ? error.message : String(error)}`); } - const remoteKeys = new Set(remotes.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); - const reservedRemoteRows = host === 'all' && inventoryPage ? remotes.filter((thread)=>modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project)).length + (cdpList?.threads.filter((thread)=>thread.location === 'remote' && modelProviderMatches(thread, options.modelProvider) && projectMatches(thread, options.project) && !remoteKeys.has((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)).length ?? 0) : 0; - const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); - let appList = null; - let appError; + const remotes = this.#listRemotes(); + let cdpList = null; try { - appList = await this.#fallbacks.listThreads({ - limit: appLimit, - cursor: options.cursor === APP_START_CURSOR ? undefined : options.cursor, - modelProviders + await this.#ensureCdp(); + cdpList = await this.#cdp.listThreads({ + limit: 200 }); } catch (error) { - appError = error; - } - let base = null; - if (appList && cdpList) base = mergeThreadLists(appList, cdpList); - else if (appList) base = appList; - else if (cdpList) base = cdpList; - else if (remotes.length) base = { - backend: 'remote-state', - limit, - threads: [] + if (isCdpFailure(error)) this.#cdpConnected = false; + else warnings.push(`CDP list failed: ${error instanceof Error ? error.message : String(error)}`); + } + if (!appRows.length && !cdpList && !remotes.length) { + throw new _errors_js__rspack_import_3.sO(warnings[0] ?? 'ChatGPT Desktop listThreads: CDP and app-server unreachable'); + } + const appList = { + backend: 'app-server', + limit: appRows.length, + threads: appRows }; - else if (cdpError) throw cdpError; - else if (appError) throw appError; - else throw new _errors_js__rspack_import_2.sO('ChatGPT Desktop listThreads: CDP and app-server unreachable'); - const result = finalizeThreadList(base, { - limit, - host, + const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const merged = finalizeThreadList({ + ...base, + threads: (0, _project_state_js__rspack_import_6.j)(base.threads) + }, { + limit: Number.MAX_SAFE_INTEGER, + host: normalizeHostFilter(options.host), modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - groupBy: options.groupBy, - remotes + remotes: (0, _project_state_js__rspack_import_6.j)(remotes) }); - const withCursor = host === 'all' || host === 'local' ? result : { - ...result, - nextCursor: null + const rows = [ + ...new Map(merged.threads.map((row)=>[ + (0, _thread_ids_js__rspack_import_7.nn)(row.threadId) ?? row.threadId, + row + ])).values() + ]; + rows.sort(compareDesktopThreads); + const fingerprint = (0, node_crypto__rspack_import_0.createHash)('sha256').update(JSON.stringify({ + filters, + port: this.#port, + rows: rows.map((row)=>[ + row.threadId, + row.updatedAt, + row.location, + row.hostId + ]) + })).digest('base64url'); + const snapshot = { + fingerprint, + port: this.#port, + filters, + createdAt: Date.now(), + rows, + backend: merged.backend, + warnings }; - return appError ? { - ...withCursor, - warnings: [ - `App-server list failed: ${appError instanceof Error ? appError.message : String(appError)}` - ] - } : withCursor; + for (const [key, value] of this.#listSnapshots){ + if (Date.now() - value.createdAt > 15 * 60000 || this.#listSnapshots.size >= 8) this.#listSnapshots.delete(key); + } + this.#listSnapshots.set(fingerprint, snapshot); + return snapshot; } async listHosts() { const remotes = this.#listRemotes(); @@ -8513,7 +8683,7 @@ var __webpack_modules__ = { } catch { localThreadCount = 0; } - const listHosts = this.#fallbacks.listHosts ?? _remote_threads_js__rspack_import_4.Kl; + const listHosts = this.#fallbacks.listHosts ?? _remote_threads_js__rspack_import_5.Kl; const fromState = listHosts(process.env, { localThreadCount }); @@ -8578,7 +8748,7 @@ var __webpack_modules__ = { let modelProvidersSource = 'thread/list-distinct'; const warnings = []; try { - const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_1.X; + const discover = this.#fallbacks.discoverModelProviders ?? _app_server_fallback_js__rspack_import_2.X; const discovered = await discover(); modelProviders = [ ...discovered.providers @@ -8599,14 +8769,35 @@ var __webpack_modules__ = { ...remotes.map((thread)=>thread.modelProvider).filter((value)=>Boolean(value)) ]) ].sort(); + let inventoryCounts = null; + try { + const filters = JSON.stringify({ + host: 'all', + modelProvider: null, + project: null, + groupBy: null + }); + const cached = [ + ...this.#listSnapshots.values() + ].find((snapshot)=>snapshot.port === this.#port && snapshot.filters === filters && Date.now() - snapshot.createdAt < 15 * 60000); + const inventory = cached ?? await this.#buildListSnapshot({}, filters); + inventoryCounts = new Map(); + for (const thread of inventory.rows){ + const hostId = thread.location === 'remote' ? thread.hostId ?? 'unknown-remote' : 'local'; + inventoryCounts.set(hostId, (inventoryCounts.get(hostId) ?? 0) + 1); + } + warnings.push(...inventory.warnings); + } catch (error) { + warnings.push(`Merged inventory count failed: ${error instanceof Error ? error.message : String(error)}`); + } return { hosts: withCounts.map((host)=>{ - const counted = host.hostId === 'local' ? { + const counted = { ...host, - threadCount: localThreadCount - } : host; + threadCount: inventoryCounts?.get(host.hostId) ?? (host.hostId === 'local' ? localThreadCount : host.threadCount) + }; if (!counted.hostName) return counted; - const name = (0, _payload_budget_js__rspack_import_6.aA)(counted.hostName); + const name = (0, _payload_budget_js__rspack_import_8.aA)(counted.hostName); return { ...counted, hostName: name.title, @@ -8633,20 +8824,22 @@ var __webpack_modules__ = { query: options.query, limit, cursor: options.cursor, - modelProviders, - project: options.project + modelProviders }); const cdpList = options.cursor ? null : await this.#tryCdpList({ limit }); const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; const appMatches = new Set(appList.threads.map((thread)=>thread.threadId)); - const withRemotes = finalizeThreadList(base, { + const withRemotes = finalizeThreadList({ + ...base, + threads: (0, _project_state_js__rspack_import_6.j)(base.threads) + }, { limit: 10000, host, modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - remotes: options.cursor ? [] : this.#listRemotes() + remotes: options.cursor ? [] : (0, _project_state_js__rspack_import_6.j)(this.#listRemotes()) }); const needle = options.query.trim().toLowerCase(); const filtered = { @@ -8677,7 +8870,7 @@ var __webpack_modules__ = { limit }, query: options.query, - threads: (cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) + threads: (0, _project_state_js__rspack_import_6.j)(cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) }; const result = finalizeThreadList(filtered, { limit, @@ -8685,7 +8878,7 @@ var __webpack_modules__ = { modelProvider: options.modelProvider?.trim() || undefined, project: options.project, groupBy: options.groupBy, - remotes: remotes.filter((thread)=>threadMatchesQuery(thread, needle)) + remotes: (0, _project_state_js__rspack_import_6.j)(remotes).filter((thread)=>threadMatchesQuery(thread, needle)) }); return { ...result, @@ -8698,7 +8891,7 @@ var __webpack_modules__ = { async readThread(options) { const limit = options.limit ?? (options.full ? 2000 : 100); const full = options.full ?? false; - if ((0, _thread_ids_js__rspack_import_5.vr)(options.threadId)) { + if ((0, _thread_ids_js__rspack_import_7.vr)(options.threadId)) { if (options.cursor) throw new Error('Temporary Desktop threads do not support read cursors'); await this.#ensureCdp(); return this.#cdp.readThread({ @@ -8715,7 +8908,7 @@ var __webpack_modules__ = { cursor: options.cursor }); } catch (appError) { - if (appError instanceof _errors_js__rspack_import_2.Rg) throw appError; + if (appError instanceof _errors_js__rspack_import_3.Rg) throw appError; if (options.cursor) throw appError; const cdpConnected = await this.#tryEnsureCdp(); if (!cdpConnected) throw appError; @@ -8735,15 +8928,15 @@ var __webpack_modules__ = { } async sendMessage(options) { if (options.threadId) { - const remote = (0, _remote_threads_js__rspack_import_4.KI)(options.threadId); - if (remote) throw new _errors_js__rspack_import_2.Rg(options.threadId, remote.hostId, remote.hostName); + const remote = (0, _remote_threads_js__rspack_import_5.KI)(options.threadId); + if (remote) throw new _errors_js__rspack_import_3.Rg(options.threadId, remote.hostId, remote.hostName); } await this.#ensureCdp(); try { return await this.#cdp.sendMessage(options); } catch (error) { - if (!(error instanceof _errors_js__rspack_import_2.fw) || !options.unarchive || !options.threadId) throw error; - await (this.#fallbacks.unarchiveThread ?? _app_server_fallback_js__rspack_import_1.qL)(options.threadId); + if (!(error instanceof _errors_js__rspack_import_3.fw) || !options.unarchive || !options.threadId) throw error; + await (this.#fallbacks.unarchiveThread ?? _app_server_fallback_js__rspack_import_2.qL)(options.threadId); return this.#cdp.sendMessage({ ...options, unarchive: false @@ -8755,8 +8948,8 @@ var __webpack_modules__ = { return this.#cdp.waitForReply(options); } async openThread(threadId, options) { - const remote = (0, _remote_threads_js__rspack_import_4.KI)(threadId); - if (remote) throw new _errors_js__rspack_import_2.Rg(threadId, remote.hostId, remote.hostName); + const remote = (0, _remote_threads_js__rspack_import_5.KI)(threadId); + if (remote) throw new _errors_js__rspack_import_3.Rg(threadId, remote.hostId, remote.hostName); await this.#ensureCdp(); return this.#cdp.openThread(threadId, options); } @@ -8785,7 +8978,7 @@ var __webpack_modules__ = { await this.#cdp.close(); } #listRemotes() { - const list = this.#fallbacks.listRemoteThreads ?? _remote_threads_js__rspack_import_4.Hx; + const list = this.#fallbacks.listRemoteThreads ?? _remote_threads_js__rspack_import_5.Hx; try { return list(); } catch { @@ -8814,7 +9007,7 @@ var __webpack_modules__ = { await this.#ensureCdp(); return await this.#cdp.listThreads(options); } catch (error) { - if (isCdpFailure(error) || error instanceof _errors_js__rspack_import_2.EH) { + if (isCdpFailure(error) || error instanceof _errors_js__rspack_import_3.EH) { if (isCdpFailure(error)) this.#cdpConnected = false; return null; } @@ -8825,11 +9018,11 @@ var __webpack_modules__ = { function mergeThreadLists(appList, cdpList) { const cdpByKey = new Map(); for (const thread of cdpList.threads){ - const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId; cdpByKey.set(key, thread); } const merged = appList.threads.map((thread)=>{ - const key = (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId; + const key = (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId; const cdp = cdpByKey.get(key); const withLocal = { ...thread, @@ -8851,7 +9044,7 @@ var __webpack_modules__ = { }; }); for (const thread of cdpList.threads){ - if (merged.some((row)=>(0, _thread_ids_js__rspack_import_5.LV)(row.threadId, thread.threadId))) continue; + if (merged.some((row)=>(0, _thread_ids_js__rspack_import_7.LV)(row.threadId, thread.threadId))) continue; merged.push(thread); } return { @@ -8866,11 +9059,11 @@ var __webpack_modules__ = { } function finalizeThreadList(base, { limit, host = 'all', modelProvider, project, groupBy, remotes }) { const remoteById = new Map(remotes.map((thread)=>[ - (0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId, + (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId, thread ])); const locals = base.threads.map((thread)=>{ - const remote = remoteById.get((0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId); + const remote = remoteById.get((0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId); if (remote) { return { ...thread, @@ -8887,12 +9080,12 @@ var __webpack_modules__ = { hostName: location === 'remote' ? thread.hostName ?? null : null }; }); - const localKeys = new Set(locals.map((thread)=>(0, _thread_ids_js__rspack_import_5.nn)(thread.threadId) ?? thread.threadId)); + const localKeys = new Set(locals.map((thread)=>(0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId)); const merged = [ ...locals ]; for (const remote of remotes){ - const key = (0, _thread_ids_js__rspack_import_5.nn)(remote.threadId) ?? remote.threadId; + const key = (0, _thread_ids_js__rspack_import_7.nn)(remote.threadId) ?? remote.threadId; if (localKeys.has(key)) continue; merged.push({ ...remote, @@ -8900,6 +9093,7 @@ var __webpack_modules__ = { hostId: remote.hostId ?? null, hostName: remote.hostName ?? null }); + localKeys.add(key); } if (remotes.length) merged.sort((a, b)=>Number(b.location === 'remote') - Number(a.location === 'remote')); const filtered = merged.filter((thread)=>{ @@ -8908,7 +9102,7 @@ var __webpack_modules__ = { if (!projectMatches(thread, project)) return false; return true; }); - const limited = filtered.slice(0, limit).map(_payload_budget_js__rspack_import_6.eX); + const limited = filtered.slice(0, limit).map(_payload_budget_js__rspack_import_8.eX); const result = { backend: remotes.length ? base.backend === 'app-server+cdp' ? 'app-server+cdp+remote-state' : base.backend === 'app-server' ? 'app-server+remote-state' : base.backend === 'cdp' ? 'cdp+remote-state' : base.backend : base.backend, limit, @@ -8936,6 +9130,14 @@ var __webpack_modules__ = { } return result; } + function compareDesktopThreads(a, b) { + const timestamp = (row)=>{ + const value = row.updatedAt ?? row.createdAt; + if (typeof value !== 'number' || !Number.isFinite(value)) return Number.NEGATIVE_INFINITY; + return value < 100000000000 ? value * 1000 : value; + }; + return timestamp(b) - timestamp(a) || a.threadId.localeCompare(b.threadId); + } function groupThreadsByHost(threads) { const groups = new Map(); for (const thread of threads){ @@ -9003,8 +9205,8 @@ var __webpack_modules__ = { ].some((value)=>typeof value === 'string' && value.toLowerCase().includes(needle)); } function isCdpFailure(error) { - if (error instanceof _errors_js__rspack_import_2.sO) return true; - if (error instanceof _errors_js__rspack_import_2.EH) return false; + if (error instanceof _errors_js__rspack_import_3.sO) return true; + if (error instanceof _errors_js__rspack_import_3.EH) return false; if (error && typeof error === 'object' && 'code' in error) { const code = String(error.code); return code === 'CDP_UNREACHABLE' || code === 'CDP_HOST_REJECTED'; @@ -9178,6 +9380,102 @@ var __webpack_modules__ = { sQ: ()=>serializedBytes }); }, + "./src/core/chatgpt-desktop/project-state.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { + var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); + var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); + function findLocalProject(nameOrId, env = process.env) { + const state = (0, _codex_remote_control_js__rspack_import_0.IT)(env); + if (!state) return null; + for (const value of Object.values(record(stateValue(state, 'local-projects')) ?? {})){ + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.name !== 'string') continue; + if (row.id !== nameOrId && row.name.toLowerCase() !== nameOrId.toLowerCase()) continue; + return { + id: row.id, + label: row.name, + rootPaths: (Array.isArray(row.rootPaths) ? row.rootPaths : []).filter((path)=>typeof path === 'string' && Boolean(path)) + }; + } + return null; + } + function record(value) { + return value && typeof value === 'object' && !Array.isArray(value) ? value : null; + } + function stateValue(state, key) { + for (const source of (0, _codex_remote_control_js__rspack_import_0.xr)(state))if (key in source) return source[key]; + return undefined; + } + function pathWithin(path, root) { + const normalized = root.replace(/\/+$/u, ''); + return path === normalized || path.startsWith(`${normalized}/`); + } + function resolveThreadProjects(threads, env = process.env) { + const state = (0, _codex_remote_control_js__rspack_import_0.IT)(env); + if (!state) return [ + ...threads + ]; + const localProjects = Object.values(record(stateValue(state, 'local-projects')) ?? {}).flatMap((value)=>{ + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.name !== 'string') return []; + return (Array.isArray(row.rootPaths) ? row.rootPaths : []).filter((path)=>typeof path === 'string' && Boolean(path)).map((rootPath)=>({ + id: row.id, + label: row.name, + rootPath + })); + }); + const remoteProjects = (Array.isArray(stateValue(state, 'remote-projects')) ? stateValue(state, 'remote-projects') : []).flatMap((value)=>{ + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.label !== 'string' || typeof row.remotePath !== 'string' || typeof row.hostId !== 'string') return []; + return [ + { + id: row.id, + label: row.label, + rootPath: row.remotePath, + hostId: row.hostId + } + ]; + }); + const assignments = record(stateValue(state, 'thread-project-assignments')) ?? {}; + const hints = record(stateValue(state, 'thread-workspace-root-hints')) ?? {}; + const projectless = new Set(Array.isArray(stateValue(state, 'projectless-thread-ids')) ? stateValue(state, 'projectless-thread-ids') : []); + return threads.map((thread)=>{ + const bare = (0, _thread_ids_js__rspack_import_1.nn)(thread.threadId) ?? thread.threadId; + const assignment = record(assignments[bare]); + const remote = thread.location === 'remote'; + const projects = remote ? remoteProjects.filter((project)=>project.hostId === thread.hostId) : localProjects; + let project = assignment && typeof assignment.projectId === 'string' ? projects.find((entry)=>entry.id === assignment.projectId) : undefined; + if (!project && !projectless.has(bare) && thread.projectId) { + project = projects.find((entry)=>entry.id === thread.projectId); + } + if (!project && !assignment && !projectless.has(bare)) { + const path = typeof hints[bare] === 'string' ? hints[bare] : typeof thread.cwd === 'string' ? thread.cwd : null; + if (path) project = projects.filter((entry)=>pathWithin(path, entry.rootPath)).sort((a, b)=>b.rootPath.length - a.rootPath.length)[0]; + } + if (project) return { + ...thread, + project: project.label, + projectId: project.id, + projectRootPath: project.rootPath + }; + if (projectless.has(bare)) return { + ...thread, + project: null, + projectId: null + }; + if (remote && typeof thread.project === 'string' && thread.project.startsWith('/')) { + return { + ...thread, + project: null + }; + } + return thread; + }); + } + __webpack_require__.d(__webpack_exports__, { + j: ()=>resolveThreadProjects, + q: ()=>findLocalProject + }); + }, "./src/core/chatgpt-desktop/remote-threads.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) { var _codex_remote_control_js__rspack_import_0 = __webpack_require__("./src/core/codex/remote-control.js"); var _thread_ids_js__rspack_import_1 = __webpack_require__("./src/core/chatgpt-desktop/thread-ids.ts"); @@ -10598,7 +10896,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop list threads', - description: 'List Desktop threads, then pass nextCursor as cursor until null. Pages may stop early at the MCP byte budget. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', + description: 'List one sorted Desktop inventory without duplicate rows. Pass nextCursor as cursor with unchanged filters until null; pages fill limit unless the MCP byte budget binds. A changed/expired inventory cursor requires restarting. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or Desktop project label/projectId; projectRootPath identifies the resolved workspace. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', annotations: { readOnlyHint: true }, @@ -10851,7 +11149,7 @@ var __webpack_modules__ = { var _core_chatgpt_desktop_routes_js__rspack_import_2 = __webpack_require__("./src/core/chatgpt-desktop/routes.ts"); const __rspack_default_export = (0, agent_bundle_routes__rspack_import_1.uO)({ title: 'ChatGPT Desktop send', - description: 'Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.', + description: 'Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. The empty view and project scope are checked before typing. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. PROJECT_UNAVAILABLE identifies a disabled project action or missing configured root; NEW_CHAT_NAVIGATION_FAILED reports an unchanged view promptly. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.', annotations: { readOnlyHint: false }, @@ -60271,7 +60569,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": true }, - "description": "List Desktop threads, then pass nextCursor as cursor until null. Pages may stop early at the MCP byte budget. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.", + "description": "List one sorted Desktop inventory without duplicate rows. Pass nextCursor as cursor with unchanged filters until null; pages fill limit unless the MCP byte budget binds. A changed/expired inventory cursor requires restarting. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or Desktop project label/projectId; projectRootPath identifies the resolved workspace. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.", "inputJsonSchema": { "additionalProperties": false, "properties": { @@ -60460,7 +60758,7 @@ var __webpack_modules__ = { "annotations": { "readOnlyHint": false }, - "description": "Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.", + "description": "Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. The empty view and project scope are checked before typing. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. PROJECT_UNAVAILABLE identifies a disabled project action or missing configured root; NEW_CHAT_NAVIGATION_FAILED reports an unchanged view promptly. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.", "inputJsonSchema": { "additionalProperties": false, "properties": { diff --git a/artifact/skills/chatgpt-desktop/SKILL.md b/artifact/skills/chatgpt-desktop/SKILL.md index 5c32b3b..1306013 100644 --- a/artifact/skills/chatgpt-desktop/SKILL.md +++ b/artifact/skills/chatgpt-desktop/SKILL.md @@ -19,7 +19,11 @@ another machine. host name from a project label. Managed SSH hosts may have no threads. 3. Use `chatgpt_desktop_list_threads` with `host`, `modelProvider`, or `project` as needed. Pass `nextCursor` back as `cursor` with the same filters until it - is `null`. Pages can stop before `limit` to stay under the MCP document cap. + is `null`. The cursor refers to a sorted merged inventory; pages normally + fill `limit` and can stop earlier at the MCP document cap. If the inventory + changed after a cursor expired, restart without one. Project labels and IDs + come from Desktop project assignments and workspace roots; `projectRootPath` + is the resolved root when available. `chatgpt_desktop_search_threads` also accepts `cursor`; keep its query and filters unchanged. Search matches the full title even when the display row has a 200-character `title` and `titleTruncated: true`. @@ -45,7 +49,8 @@ or app-server. The local Mac cannot fetch that remote history through CDP. thread remains readable through `chatgpt_desktop_read_thread`. - `chatgpt_desktop_send` with `threadId` sends to that conversation. Omit `threadId` and `project` to start outside a project. Omit `threadId` and set - `project` to start inside that project. Send once. A new-thread receipt may + `project` to start inside that project. The tool verifies the empty new-chat + view and its project selection before typing. Send once. A new-thread receipt may include `temporaryThreadId` and resolves `threadId` to the durable `local:` before returning. Keep both until the durable ID is confirmed; use the durable ID for later work. @@ -59,7 +64,11 @@ the user wants the archive state changed; this explicitly calls app-server `thread/unarchive` and retries once. Never unarchive merely to read or open. `COMPOSER_HAS_DRAFT` means the user's draft would be disturbed; leave it for -the operator. `CDP_UNREACHABLE` requires restoring the local Desktop CDP +the operator. `PROJECT_UNAVAILABLE` means Desktop disabled a project's new-chat +action, often because its configured workspace root no longer exists; correct +the project root in Desktop before retrying. `NEW_CHAT_NAVIGATION_FAILED` means +the button did not open the requested empty view within three seconds; inspect +Desktop before retrying. `CDP_UNREACHABLE` requires restoring the local Desktop CDP endpoint. App-server failures, including oversized frames, appear as errors or read `warnings` with `complete: false`; inspect the partial result and source status before continuing. A send with unknown delivery must not be repeated diff --git a/docs/chatgpt-desktop-cdp.md b/docs/chatgpt-desktop-cdp.md index cd49955..dc58eca 100644 --- a/docs/chatgpt-desktop-cdp.md +++ b/docs/chatgpt-desktop-cdp.md @@ -107,11 +107,25 @@ Surfaced list fields: `id`, `name`, `preview`, `cwd`, `createdAt` / `updatedAt` (unix s), `section {id,name}` (Pinned → `pinned: true`), `projectId`, `status`, `modelProvider`, `model`, `originator`. `archived` is a list filter, not a field. -List and search pages can stop before `limit` to stay under the document cap. +List pages use one merged, timestamp-sorted inventory with thread ID as a +deterministic tiebreak. CDP/sidebar and remote-summary rows are deduplicated +before paging, so a full cursor walk includes each ID once. The cursor refers +to that inventory; after it expires or the inventory changes during recovery, +restart without a cursor. List and search pages can stop before `limit` to stay +under the document cap. Display titles collapse whitespace and stop at 200 characters with `titleTruncated: true`; search still matches the full source title. Pass `nextCursor` back with unchanged filters and query. +Project labels and IDs are resolved from Desktop's local/remote projects, +thread-project assignments, workspace-root hints, and cwd. The row's +`projectRootPath` shows the matched root. A new chat is checked for an empty +composer and the requested project before text is inserted. Projectless new +chat clears a project retained from the previous thread. If Desktop disables +the project action because its configured root is unavailable, send returns +`PROJECT_UNAVAILABLE` before typing. A click that leaves the old view in place +returns `NEW_CHAT_NAVIGATION_FAILED` after a short observation. + ### Host and modelProvider filters (separate) `chatgpt_desktop_list_threads` / search accept these independent filters: diff --git a/src/core/chatgpt-desktop/app-server-fallback.ts b/src/core/chatgpt-desktop/app-server-fallback.ts index efa7bd0..da22729 100644 --- a/src/core/chatgpt-desktop/app-server-fallback.ts +++ b/src/core/chatgpt-desktop/app-server-fallback.ts @@ -58,7 +58,7 @@ export async function appServerListThreads({ let fetchLimit = Math.min(limit, 25); if (cursor?.startsWith(LIST_PAGE_PREFIX)) { const state = decodePageCursor(LIST_PAGE_PREFIX, cursor); - if (!Number.isSafeInteger(state.skip) || state.skip < 1 + if (!Number.isSafeInteger(state.skip) || state.skip < 0 || !Number.isSafeInteger(state.fetchLimit) || state.fetchLimit < 1 || state.fetchLimit > 25 || (state.cursor !== null && typeof state.cursor !== 'string')) { throw new Error('Invalid ChatGPT Desktop list page cursor'); @@ -67,36 +67,46 @@ export async function appServerListThreads({ skip = state.skip; fetchLimit = state.fetchLimit; } - const out = await listCodexThreads({ limit: fetchLimit, cursor: sourceCursor, modelProviders }); - if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); const base = { backend: 'app-server' as const, limit, modelProvider: modelProviders.length === 1 ? modelProviders[0] : undefined, }; const threads: ChatGptDesktopThread[] = []; - let consumed = skip; - for (const raw of out.threads.slice(skip)) { - if (threads.length >= limit) break; - let row = compactThreadRow(mapListedThread(raw)); - const probe = { ...base, threads: [...threads, row], nextCursor: LIST_PAGE_PREFIX, exitCode: 0 }; - if (serializedBytes(probe) > DESKTOP_RESULT_BUDGET_BYTES) { - if (threads.length) break; - row = minimalThreadRow(row); - if (serializedBytes({ ...base, threads: [row], nextCursor: LIST_PAGE_PREFIX, exitCode: 0 }) > DESKTOP_RESULT_BUDGET_BYTES) { - throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + const seen = new Set(); + for (let page = 0; page < 400; page++) { + const out = await listCodexThreads({ limit: fetchLimit, cursor: sourceCursor, modelProviders }); + if (skip > out.threads.length) throw new Error('ChatGPT Desktop list page cursor is stale'); + for (let index = skip; index < out.threads.length; index++) { + let row = compactThreadRow(mapListedThread(out.threads[index])); + const probe = { ...base, threads: [...threads, row], nextCursor: LIST_PAGE_PREFIX, exitCode: 0 }; + if (serializedBytes(probe) > DESKTOP_RESULT_BUDGET_BYTES) { + if (threads.length) return { ...base, threads, + nextCursor: encodePageCursor(LIST_PAGE_PREFIX, { cursor: sourceCursor ?? null, skip: index, fetchLimit }), + warnings: ['List page stopped at the MCP byte budget; continue with nextCursor'] }; + row = minimalThreadRow(row); + if (serializedBytes({ ...base, threads: [row], nextCursor: LIST_PAGE_PREFIX, exitCode: 0 }) > DESKTOP_RESULT_BUDGET_BYTES) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); + } + } + threads.push(row); + if (threads.length >= limit) { + const nextCursor = index + 1 < out.threads.length + ? encodePageCursor(LIST_PAGE_PREFIX, { cursor: sourceCursor ?? null, skip: index + 1, fetchLimit }) + : out.nextCursor ?? null; + return { ...base, threads, nextCursor }; } } - threads.push(row); - consumed++; + if (out.nextCursor == null) return { ...base, threads, nextCursor: null }; + if (typeof out.nextCursor !== 'string' || !out.nextCursor || seen.has(out.nextCursor)) { + throw new Error('ChatGPT Desktop list returned an invalid or repeated cursor'); + } + seen.add(out.nextCursor); + sourceCursor = out.nextCursor; + skip = 0; } - const nextCursor = consumed < out.threads.length - ? encodePageCursor(LIST_PAGE_PREFIX, { cursor: sourceCursor ?? null, skip: consumed, fetchLimit }) - : out.nextCursor ?? null; - return { - ...base, threads, nextCursor, - ...(consumed < out.threads.length ? { warnings: ['List page stopped at the MCP byte budget; continue with nextCursor'] } : {}), - }; + return { ...base, threads, nextCursor: sourceCursor, + warnings: ['List stopped after 400 app-server pages; continue with nextCursor'] }; } export async function appServerSearchThreads({ diff --git a/src/core/chatgpt-desktop/cdp-adapter.ts b/src/core/chatgpt-desktop/cdp-adapter.ts index 0487d8b..4b88fc8 100644 --- a/src/core/chatgpt-desktop/cdp-adapter.ts +++ b/src/core/chatgpt-desktop/cdp-adapter.ts @@ -1,5 +1,6 @@ +import { existsSync } from 'node:fs'; import type { ChatGptDesktopAdapter } from './adapter.js'; -import { ArchivedThreadError, CdpUnreachableError } from './errors.js'; +import { ArchivedThreadError, CdpUnreachableError, ProjectUnavailableError } from './errors.js'; import { CdpSession } from './cdp-session.js'; import { DEFAULT_CONVERSATION_RESOLVE_MS, @@ -21,6 +22,7 @@ import { } from './cdp-dom.js'; import { isTemporaryDesktopThreadId, toAppServerThreadId, toDesktopThreadId } from './thread-ids.js'; import { resolveCdpPort } from './loopback.js'; +import { findLocalProject } from './project-state.js'; import type { ChatGptDesktopStatus, ChatGptDesktopTarget, @@ -119,8 +121,14 @@ export class CdpChatGptDesktopAdapter implements ChatGptDesktopAdapter { if (threadId) { await this.#openAndWait(sessionId, threadId, openTimeoutMs); } else { - await startNewChatInDom(this.#requireSession(), sessionId, { project }); - await waitForLoadingTaskGone(this.#requireSession(), sessionId, { timeoutMs: openTimeoutMs, threadId: 'new' }); + const localProject = project ? findLocalProject(project) : null; + if (localProject && !localProject.rootPaths.some((path) => existsSync(path))) { + throw new ProjectUnavailableError(localProject.label, + `none of its configured workspace roots exists: ${localProject.rootPaths.map((path) => JSON.stringify(path)).join(', ') || '(none)'}. Update the Desktop project root before sending.`); + } + await startNewChatInDom(this.#requireSession(), sessionId, { + project: localProject?.label ?? project, projectId: localProject?.id, + }); const threads = await listThreadsFromDom(this.#requireSession(), sessionId, { limit: 20 }); const temp = threads.find((t) => t.threadId.startsWith(TEMP_THREAD_ID_PREFIX) && t.selected) ?? threads.find((t) => t.threadId.startsWith(TEMP_THREAD_ID_PREFIX)); diff --git a/src/core/chatgpt-desktop/cdp-dom.ts b/src/core/chatgpt-desktop/cdp-dom.ts index 0e87f9c..a0961a8 100644 --- a/src/core/chatgpt-desktop/cdp-dom.ts +++ b/src/core/chatgpt-desktop/cdp-dom.ts @@ -7,7 +7,7 @@ import type { ChatGptDesktopTarget, ChatGptDesktopThread, ChatGptDesktopTurn } from './types.js'; import type { CdpSession } from './cdp-session.js'; -import { ArchivedThreadError, ComposerDraftError } from './errors.js'; +import { ArchivedThreadError, ComposerDraftError, NewChatNavigationError, ProjectUnavailableError } from './errors.js'; import { LOCAL_THREAD_ID_PREFIX, isTemporaryDesktopThreadId, @@ -251,17 +251,18 @@ export function navigateToThreadExpression(threadId: string): string { })()`; } -export function startNewChatExpression(project?: string): string { +export function startNewChatExpression(project?: string, projectId?: string): string { const projectSel = project ? newChatInProjectSelector(project) : null; return `(() => { const projectSel = ${JSON.stringify(projectSel)}; if (projectSel) { - const preferred = document.querySelector(projectSel); + const preferred = ${projectId ? `document.querySelector('[data-app-action-sidebar-project-id=${JSON.stringify(projectId)}]')?.querySelector(projectSel) ||` : ''} document.querySelector(projectSel); if (preferred) { - const row = preferred.closest('.group') || preferred.parentElement; + const row = preferred.closest('[data-app-action-sidebar-project-row]') || preferred.parentElement; row?.scrollIntoView({ block: 'center' }); const rowBox = row?.getBoundingClientRect(); return { ok: true, via: 'project', project: ${JSON.stringify(project ?? null)}, + disabled: preferred.disabled || preferred.getAttribute('aria-disabled') === 'true', hoverX: rowBox?.left + rowBox?.width / 2, hoverY: rowBox?.top + rowBox?.height / 2 }; } return { ok: false, error: 'project-not-found' }; @@ -274,16 +275,44 @@ export function startNewChatExpression(project?: string): string { })()`; } -export function projectButtonBoxExpression(project: string): string { +export function projectButtonBoxExpression(project: string, projectId?: string): string { return `(() => { - const button = document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); + const button = ${projectId ? `document.querySelector('[data-app-action-sidebar-project-id=${JSON.stringify(projectId)}]')?.querySelector(${JSON.stringify(newChatInProjectSelector(project))}) ||` : ''} document.querySelector(${JSON.stringify(newChatInProjectSelector(project))}); if (!button) return null; const box = button.getBoundingClientRect(); return { x: box.left + box.width / 2, y: box.top + box.height / 2, - visible: box.width > 0 && box.height > 0 && getComputedStyle(button.parentElement).opacity !== '0' }; + disabled: button.disabled || button.getAttribute('aria-disabled') === 'true', + visible: box.width > 0 && box.height > 0 && box.x >= 0 && box.y >= 0 + && box.x < innerWidth && box.y < innerHeight && getComputedStyle(button.parentElement).opacity !== '0' }; })()`; } +/** The new-chat route is `/`; the composer exposes its selected project. */ +export function newChatViewExpression(project?: string): string { + return `(() => { + const root = window.__codexRoot?._internalRoot?.current; + const queue = [root]; let scanned = 0; let path = ''; + while (queue.length && scanned++ < 10000) { + const fiber = queue.shift(); if (!fiber) continue; + const router = fiber.memoizedProps?.router; + if (router?.navigate && router?.state?.location) { path = router.state.location.pathname; break; } + if (fiber.child) queue.push(fiber.child); + if (fiber.sibling) queue.push(fiber.sibling); + } + const composer = !!document.querySelector(${JSON.stringify(COMPOSER_SELECTOR)}); + const scope = document.querySelector('[data-composer-navigation-target="workspace-project"]')?.getAttribute('aria-label') || ''; + const expected = ${JSON.stringify(project ? `Change project: ${project}` : '')}; + return { ready: path === '/' && composer && (expected ? scope === expected : (!scope || scope === 'Choose project')), path, composer, scope }; + })()`; +} + +export const CLEAR_NEW_CHAT_PROJECT_EXPRESSION = `(() => { + const button = document.querySelector('[data-clear-project-button="true"]'); + if (!button || button.disabled) return false; + button.click(); + return true; +})()`; + export const LOADING_TASK_GONE_EXPRESSION = `(() => { const surfacePrefix = ${JSON.stringify(MAIN_CONTENT_SURFACE_CLASS_PREFIX)}; const mains = Array.from(document.querySelectorAll('main')); @@ -492,10 +521,10 @@ export async function waitForLoadingTaskGone( export async function startNewChatInDom( session: CdpSession, sessionId: string, - { project }: { project?: string } = {}, + { project, projectId, navigationTimeoutMs = 3000 }: { project?: string; projectId?: string; navigationTimeoutMs?: number } = {}, ): Promise<{ via: string }> { - const result = await session.evaluate<{ ok: boolean; via?: string; error?: string; x?: number; y?: number; hoverX?: number; hoverY?: number }>( - startNewChatExpression(project), + const result = await session.evaluate<{ ok: boolean; via?: string; error?: string; disabled?: boolean; hoverX?: number; hoverY?: number }>( + startNewChatExpression(project, projectId), { sessionId }, ); if (!result?.ok) { @@ -506,11 +535,13 @@ export async function startNewChatInDom( ); } if (result.via === 'project') { + if (result.disabled) throw new ProjectUnavailableError(project!, 'the Desktop project new-chat action is disabled; check its configured workspace root'); if (![result.hoverX, result.hoverY].every(Number.isFinite)) { throw new Error(`ChatGPT Desktop project button has no visible box for ${JSON.stringify(project)}`); } await session.send('Input.dispatchMouseEvent', { type: 'mouseMoved', x: result.hoverX, y: result.hoverY }, { sessionId }); - const button = await session.evaluate<{ x: number; y: number; visible: boolean } | null>(projectButtonBoxExpression(project!), { sessionId }); + const button = await session.evaluate<{ x: number; y: number; visible: boolean; disabled: boolean } | null>(projectButtonBoxExpression(project!, projectId), { sessionId }); + if (button?.disabled) throw new ProjectUnavailableError(project!, 'the Desktop project new-chat action is disabled; check its configured workspace root'); if (!button?.visible || !Number.isFinite(button.x) || !Number.isFinite(button.y)) { throw new Error(`ChatGPT Desktop project button did not appear after hover for ${JSON.stringify(project)}`); } @@ -518,7 +549,17 @@ export async function startNewChatInDom( await session.send('Input.dispatchMouseEvent', { type: 'mousePressed', x: button.x, y: button.y, button: 'left', clickCount: 1 }, { sessionId }); await session.send('Input.dispatchMouseEvent', { type: 'mouseReleased', x: button.x, y: button.y, button: 'left', clickCount: 1 }, { sessionId }); } - return { via: result.via ?? 'unknown' }; + let observed = { ready: false, path: '', composer: false, scope: '' }; + const deadline = Date.now() + navigationTimeoutMs; + while (Date.now() < deadline) { + observed = await session.evaluate(newChatViewExpression(project), { sessionId }); + if (observed?.ready) return { via: result.via ?? 'unknown' }; + if (!project && observed?.path === '/' && observed?.composer && observed.scope.startsWith('Change project: ')) { + await session.evaluate(CLEAR_NEW_CHAT_PROJECT_EXPRESSION, { sessionId }); + } + await delay(100); + } + throw new NewChatNavigationError(project, `route ${JSON.stringify(observed?.path)}, composer ${Boolean(observed?.composer)}, project ${JSON.stringify(observed?.scope)}`); } export async function focusComposer( diff --git a/src/core/chatgpt-desktop/errors.ts b/src/core/chatgpt-desktop/errors.ts index 47f2e5a..e4118ff 100644 --- a/src/core/chatgpt-desktop/errors.ts +++ b/src/core/chatgpt-desktop/errors.ts @@ -26,6 +26,29 @@ export class ComposerDraftError extends Error { } } +/** Desktop cannot start a chat in a project whose action is disabled or root is unavailable. */ +export class ProjectUnavailableError extends Error { + readonly code = 'PROJECT_UNAVAILABLE' as const; + readonly reason = 'project-unavailable' as const; + readonly delivery = 'rejected' as const; + + constructor(project: string, detail: string) { + super(`ChatGPT Desktop cannot start a chat in project ${JSON.stringify(project)}: ${detail}`); + this.name = 'ProjectUnavailableError'; + } +} + +export class NewChatNavigationError extends Error { + readonly code = 'NEW_CHAT_NAVIGATION_FAILED' as const; + readonly reason = 'new-chat-navigation-failed' as const; + readonly delivery = 'rejected' as const; + + constructor(project: string | undefined, observed: string) { + super(`ChatGPT Desktop new-chat action did not open ${project ? `project ${JSON.stringify(project)}` : 'a projectless chat'}; observed ${observed}`); + this.name = 'NewChatNavigationError'; + } +} + /** Typed failure when a ChatGPT Desktop CDP/DOM operation is not yet implemented. */ export class NotImplementedError extends Error { readonly code = 'NOT_IMPLEMENTED' as const; diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index 4e5a72e..f250ae4 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -1,3 +1,4 @@ +import { createHash } from 'node:crypto'; import type { ChatGptDesktopAdapter } from './adapter.js'; import { CdpChatGptDesktopAdapter } from './cdp-adapter.js'; import { @@ -11,7 +12,8 @@ import { import { ArchivedThreadError, CdpUnreachableError, NotImplementedError, RemoteThreadNotLoadedError } from './errors.js'; import { resolveCdpPort } from './loopback.js'; import { findRemoteThread, listDiscoveredHosts, listRemoteThreadsFromState } from './remote-threads.js'; -import { compactThreadRow, compactThreadTitle, DESKTOP_RESULT_BUDGET_BYTES, serializedBytes } from './payload-budget.js'; +import { resolveThreadProjects } from './project-state.js'; +import { compactThreadRow, compactThreadTitle, decodePageCursor, DESKTOP_RESULT_BUDGET_BYTES, encodePageCursor, minimalThreadRow, serializedBytes } from './payload-budget.js'; import { isTemporaryDesktopThreadId, threadIdsEquivalent, @@ -53,8 +55,16 @@ const defaultFallbacks: ChatGptDesktopFallbacks = { discoverModelProviders, }; -const REMOTE_PAGE_CURSOR = 'desktop-remote-page:'; -const APP_START_CURSOR = 'desktop-app-start'; +const MERGED_LIST_CURSOR = 'desktop-merged-list-v1:'; +type ListSnapshot = { + fingerprint: string; + port: number; + filters: string; + createdAt: number; + rows: readonly ChatGptDesktopThread[]; + backend: ListThreadsResult['backend']; + warnings: readonly string[]; +}; export type ListThreadsOptions = { limit?: number; @@ -90,6 +100,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { #port: number; #cdpConnected = false; #fallbacks: ChatGptDesktopFallbacks; + #listSnapshots = new Map(); constructor( cdp: ChatGptDesktopAdapter = new CdpChatGptDesktopAdapter(), @@ -119,93 +130,122 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { async listThreads(options: ListThreadsOptions = {}): Promise { const limit = options.limit ?? 50; - const host = normalizeHostFilter(options.host); - const modelProviders = modelProvidersFromFilter(options.modelProvider); - const remoteOffset = options.cursor?.startsWith(REMOTE_PAGE_CURSOR) - ? Number(options.cursor.slice(REMOTE_PAGE_CURSOR.length)) : null; - if (remoteOffset !== null && (!Number.isSafeInteger(remoteOffset) || remoteOffset < 1)) { - throw new Error('Invalid ChatGPT Desktop remote page cursor'); - } - const inventoryPage = !options.cursor || remoteOffset !== null; - const remotes = inventoryPage ? this.#listRemotes() : []; - let cdpList: ListThreadsResult | null = null; - let cdpError: unknown; - try { - if (inventoryPage) { - await this.#ensureCdp(); - cdpList = await this.#cdp.listThreads({ limit: 200 }); + const filters = JSON.stringify({ + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || null, + project: options.project?.trim() || null, + groupBy: options.groupBy ?? null, + }); + let snapshot: ListSnapshot; + let offset = 0; + if (options.cursor) { + const state = decodePageCursor<{ fingerprint: string; offset: number; port: number; filters: string }>( + MERGED_LIST_CURSOR, options.cursor); + if (state.port !== this.#port || state.filters !== filters || !Number.isSafeInteger(state.offset) || state.offset < 1 + || typeof state.fingerprint !== 'string') { + throw new Error('ChatGPT Desktop list cursor does not match the port or filters'); } - } catch (error) { - if (isCdpFailure(error)) { - this.#cdpConnected = false; - } else { - cdpError = error; + offset = state.offset; + snapshot = this.#listSnapshots.get(state.fingerprint) ?? await this.#buildListSnapshot(options, filters); + if (snapshot.fingerprint !== state.fingerprint || snapshot.filters !== filters || snapshot.port !== this.#port) { + throw new Error('ChatGPT Desktop thread inventory changed; restart listing without a cursor'); } + } else { + snapshot = await this.#buildListSnapshot(options, filters); } - - if (inventoryPage && host !== 'local') { - const remoteInventory = finalizeThreadList({ - backend: cdpList?.backend ?? 'remote-state', limit: 10_000, - threads: cdpList?.threads.filter((thread) => thread.location === 'remote') ?? [], - }, { limit: 10_000, host, modelProvider: options.modelProvider, project: options.project, remotes }); - const offset = remoteOffset ?? 0; - if (remoteOffset !== null || remoteInventory.threads.length >= limit) { - const page: ChatGptDesktopThread[] = []; - for (const thread of remoteInventory.threads.slice(offset, offset + limit)) { - const row = compactThreadRow(thread); - if (serializedBytes({ ...remoteInventory, threads: [...page, row], nextCursor: REMOTE_PAGE_CURSOR, - ...(options.groupBy === 'host' ? { groups: groupThreadsByHost([...page, row]) } : {}) }) > DESKTOP_RESULT_BUDGET_BYTES) { - if (!page.length) throw new Error('ChatGPT Desktop remote thread row exceeds the MCP result byte budget'); - break; - } - page.push(row); + if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop list cursor is out of range'); + const host = normalizeHostFilter(options.host); + const rows: ChatGptDesktopThread[] = []; + const base = { + backend: snapshot.backend, limit, host, + ...(options.modelProvider?.trim() ? { modelProvider: options.modelProvider.trim() } : {}), + ...(options.project ? { project: options.project } : {}), + ...(options.groupBy === 'host' ? { groupBy: 'host' as const } : {}), + }; + for (const source of snapshot.rows.slice(offset, offset + limit)) { + let row = source; + const candidate = [...rows, row]; + const probe = { ...base, threads: candidate, nextCursor: MERGED_LIST_CURSOR, + ...(options.groupBy === 'host' ? { groups: groupThreadsByHost(candidate) } : {}), + warnings: snapshot.warnings, exitCode: 0 }; + if (serializedBytes(probe) > DESKTOP_RESULT_BUDGET_BYTES) { + if (rows.length) break; + row = minimalThreadRow(row); + const minimal = [row]; + if (serializedBytes({ ...base, threads: minimal, nextCursor: MERGED_LIST_CURSOR, + ...(options.groupBy === 'host' ? { groups: groupThreadsByHost(minimal) } : {}), + warnings: snapshot.warnings, exitCode: 0 }) > DESKTOP_RESULT_BUDGET_BYTES) { + throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); } - const nextOffset = offset + page.length; - const nextCursor = nextOffset < remoteInventory.threads.length - ? `${REMOTE_PAGE_CURSOR}${nextOffset}` : host === 'all' ? APP_START_CURSOR : null; - return { ...remoteInventory, threads: page, limit, nextCursor, - ...(options.groupBy === 'host' ? { groupBy: 'host', groups: groupThreadsByHost(page) } : {}) }; } + rows.push(row); + } + const nextOffset = offset + rows.length; + const nextCursor = nextOffset < snapshot.rows.length + ? encodePageCursor(MERGED_LIST_CURSOR, { fingerprint: snapshot.fingerprint, offset: nextOffset, + port: this.#port, filters }) : null; + const warnings = [...snapshot.warnings]; + if (rows.length < Math.min(limit, snapshot.rows.length - offset)) { + warnings.push('List page stopped at the MCP byte budget; continue with nextCursor'); } + return { ...base, threads: rows, nextCursor, + ...(options.groupBy === 'host' ? { groups: groupThreadsByHost(rows) } : {}), + ...(warnings.length ? { warnings } : {}) }; + } - const remoteKeys = new Set(remotes.map((thread) => toAppServerThreadId(thread.threadId) ?? thread.threadId)); - const reservedRemoteRows = host === 'all' && inventoryPage - ? remotes.filter((thread) => modelProviderMatches(thread, options.modelProvider) - && projectMatches(thread, options.project)).length - + (cdpList?.threads.filter((thread) => thread.location === 'remote' - && modelProviderMatches(thread, options.modelProvider) - && projectMatches(thread, options.project) - && !remoteKeys.has(toAppServerThreadId(thread.threadId) ?? thread.threadId)).length ?? 0) - : 0; - const appLimit = Math.max(1, limit - Math.min(limit - 1, reservedRemoteRows)); - let appList: ListThreadsResult | null = null; - let appError: unknown; + async #buildListSnapshot(options: ListThreadsOptions, filters: string): Promise { + const appRows: ChatGptDesktopThread[] = []; + const warnings: string[] = []; + let appCursor: string | undefined; + let appComplete = false; + const seenCursors = new Set(); + const modelProviders = modelProvidersFromFilter(options.modelProvider); + try { + for (let page = 0; page < 400; page++) { + const out = await this.#fallbacks.listThreads({ limit: 200, cursor: appCursor, modelProviders }); + appRows.push(...out.threads); + if (out.warnings) warnings.push(...out.warnings); + if (!out.nextCursor) { appComplete = true; break; } + if (seenCursors.has(out.nextCursor)) throw new Error('App-server list returned a repeated cursor'); + seenCursors.add(out.nextCursor); + appCursor = out.nextCursor; + } + if (!appComplete) warnings.push('App-server inventory stopped after 400 pages'); + } catch (error) { + warnings.push(`App-server list failed: ${error instanceof Error ? error.message : String(error)}`); + } + const remotes = this.#listRemotes(); + let cdpList: ListThreadsResult | null = null; try { - appList = await this.#fallbacks.listThreads({ limit: appLimit, - cursor: options.cursor === APP_START_CURSOR ? undefined : options.cursor, modelProviders }); + await this.#ensureCdp(); + cdpList = await this.#cdp.listThreads({ limit: 200 }); } catch (error) { - appError = error; + if (isCdpFailure(error)) this.#cdpConnected = false; + else warnings.push(`CDP list failed: ${error instanceof Error ? error.message : String(error)}`); } - - let base: ListThreadsResult | null = null; - if (appList && cdpList) base = mergeThreadLists(appList, cdpList); - else if (appList) base = appList; - else if (cdpList) base = cdpList; - else if (remotes.length) base = { backend: 'remote-state', limit, threads: [] }; - else if (cdpError) throw cdpError; - else if (appError) throw appError; - else throw new CdpUnreachableError('ChatGPT Desktop listThreads: CDP and app-server unreachable'); - - const result = finalizeThreadList(base, { - limit, - host, + if (!appRows.length && !cdpList && !remotes.length) { + throw new CdpUnreachableError(warnings[0] ?? 'ChatGPT Desktop listThreads: CDP and app-server unreachable'); + } + const appList: ListThreadsResult = { backend: 'app-server', limit: appRows.length, threads: appRows }; + const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const merged = finalizeThreadList({ ...base, threads: resolveThreadProjects(base.threads) }, { + limit: Number.MAX_SAFE_INTEGER, + host: normalizeHostFilter(options.host), modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - groupBy: options.groupBy, - remotes, + remotes: resolveThreadProjects(remotes), }); - const withCursor = host === 'all' || host === 'local' ? result : { ...result, nextCursor: null }; - return appError ? { ...withCursor, warnings: [`App-server list failed: ${appError instanceof Error ? appError.message : String(appError)}`] } : withCursor; + const rows = [...new Map(merged.threads.map((row) => [toAppServerThreadId(row.threadId) ?? row.threadId, row])).values()]; + rows.sort(compareDesktopThreads); + const fingerprint = createHash('sha256').update(JSON.stringify({ filters, port: this.#port, + rows: rows.map((row) => [row.threadId, row.updatedAt, row.location, row.hostId]) })).digest('base64url'); + const snapshot: ListSnapshot = { fingerprint, port: this.#port, filters, createdAt: Date.now(), + rows, backend: merged.backend, warnings }; + for (const [key, value] of this.#listSnapshots) { + if (Date.now() - value.createdAt > 15 * 60_000 || this.#listSnapshots.size >= 8) this.#listSnapshots.delete(key); + } + this.#listSnapshots.set(fingerprint, snapshot); + return snapshot; } async listHosts(): Promise { @@ -296,9 +336,25 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { ...modelProviders, ...remotes.map((thread) => thread.modelProvider).filter((value): value is string => Boolean(value)), ])].sort(); + let inventoryCounts: Map | null = null; + try { + const filters = JSON.stringify({ host: 'all', modelProvider: null, project: null, groupBy: null }); + const cached = [...this.#listSnapshots.values()].find((snapshot) => + snapshot.port === this.#port && snapshot.filters === filters && Date.now() - snapshot.createdAt < 15 * 60_000); + const inventory = cached ?? await this.#buildListSnapshot({}, filters); + inventoryCounts = new Map(); + for (const thread of inventory.rows) { + const hostId = thread.location === 'remote' ? thread.hostId ?? 'unknown-remote' : 'local'; + inventoryCounts.set(hostId, (inventoryCounts.get(hostId) ?? 0) + 1); + } + warnings.push(...inventory.warnings); + } catch (error) { + warnings.push(`Merged inventory count failed: ${error instanceof Error ? error.message : String(error)}`); + } return { hosts: withCounts.map((host) => { - const counted = host.hostId === 'local' ? { ...host, threadCount: localThreadCount } : host; + const counted = { ...host, threadCount: inventoryCounts?.get(host.hostId) + ?? (host.hostId === 'local' ? localThreadCount : host.threadCount) }; if (!counted.hostName) return counted; const name = compactThreadTitle(counted.hostName); return { ...counted, hostName: name.title, @@ -332,17 +388,16 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { limit, cursor: options.cursor, modelProviders, - project: options.project, }); const cdpList = options.cursor ? null : await this.#tryCdpList({ limit }); const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; const appMatches = new Set(appList.threads.map((thread) => thread.threadId)); - const withRemotes = finalizeThreadList(base, { + const withRemotes = finalizeThreadList({ ...base, threads: resolveThreadProjects(base.threads) }, { limit: 10_000, host, modelProvider: options.modelProvider?.trim() || undefined, project: options.project, - remotes: options.cursor ? [] : this.#listRemotes(), + remotes: options.cursor ? [] : resolveThreadProjects(this.#listRemotes()), }); const needle = options.query.trim().toLowerCase(); const filtered = { @@ -368,7 +423,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { const filtered = { ...(cdpList ?? { backend: 'app-server' as const, limit }), query: options.query, - threads: (cdpList?.threads ?? []).filter((thread) => threadMatchesQuery(thread, needle)), + threads: resolveThreadProjects(cdpList?.threads ?? []).filter((thread) => threadMatchesQuery(thread, needle)), }; const result = finalizeThreadList(filtered, { limit, @@ -376,7 +431,7 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { modelProvider: options.modelProvider?.trim() || undefined, project: options.project, groupBy: options.groupBy, - remotes: remotes.filter((thread) => threadMatchesQuery(thread, needle)), + remotes: resolveThreadProjects(remotes).filter((thread) => threadMatchesQuery(thread, needle)), }); return { ...result, warnings: [`App-server search failed: ${appError instanceof Error ? appError.message : String(appError)}`] }; } @@ -617,6 +672,7 @@ export function finalizeThreadList( hostId: remote.hostId ?? null, hostName: remote.hostName ?? null, }); + localKeys.add(key); } if (remotes.length) merged.sort((a, b) => Number(b.location === 'remote') - Number(a.location === 'remote')); @@ -647,6 +703,15 @@ export function finalizeThreadList( return result; } +function compareDesktopThreads(a: ChatGptDesktopThread, b: ChatGptDesktopThread): number { + const timestamp = (row: ChatGptDesktopThread) => { + const value = row.updatedAt ?? row.createdAt; + if (typeof value !== 'number' || !Number.isFinite(value)) return Number.NEGATIVE_INFINITY; + return value < 100_000_000_000 ? value * 1000 : value; + }; + return timestamp(b) - timestamp(a) || a.threadId.localeCompare(b.threadId); +} + export function groupThreadsByHost( threads: readonly ChatGptDesktopThread[], ): ChatGptDesktopHostGroup[] { diff --git a/src/core/chatgpt-desktop/project-state.ts b/src/core/chatgpt-desktop/project-state.ts new file mode 100644 index 0000000..912db38 --- /dev/null +++ b/src/core/chatgpt-desktop/project-state.ts @@ -0,0 +1,88 @@ +/** Resolve Desktop project labels from its persisted project/assignment state. */ +import { codexStateEntries, loadCodexGlobalState } from '../codex/remote-control.js'; +import { toAppServerThreadId } from './thread-ids.js'; +import type { ChatGptDesktopThread } from './types.js'; + +type Project = { id: string; label: string; rootPath: string; hostId?: string }; + +export function findLocalProject( + nameOrId: string, + env: NodeJS.ProcessEnv = process.env, +): { id: string; label: string; rootPaths: string[] } | null { + const state = loadCodexGlobalState(env); + if (!state) return null; + for (const value of Object.values(record(stateValue(state, 'local-projects')) ?? {})) { + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.name !== 'string') continue; + if (row.id !== nameOrId && row.name.toLowerCase() !== nameOrId.toLowerCase()) continue; + return { id: row.id, label: row.name, + rootPaths: (Array.isArray(row.rootPaths) ? row.rootPaths : []) + .filter((path): path is string => typeof path === 'string' && Boolean(path)) }; + } + return null; +} + +function record(value: unknown): Record | null { + return value && typeof value === 'object' && !Array.isArray(value) ? value as Record : null; +} + +function stateValue(state: Record, key: string): unknown { + for (const source of codexStateEntries(state)) if (key in source) return source[key]; + return undefined; +} + +function pathWithin(path: string, root: string): boolean { + const normalized = root.replace(/\/+$/u, ''); + return path === normalized || path.startsWith(`${normalized}/`); +} + +export function resolveThreadProjects( + threads: readonly ChatGptDesktopThread[], + env: NodeJS.ProcessEnv = process.env, +): ChatGptDesktopThread[] { + const state = loadCodexGlobalState(env); + if (!state) return [...threads]; + const localProjects = Object.values(record(stateValue(state, 'local-projects')) ?? {}) + .flatMap((value): Project[] => { + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.name !== 'string') return []; + return (Array.isArray(row.rootPaths) ? row.rootPaths : []) + .filter((path): path is string => typeof path === 'string' && Boolean(path)) + .map((rootPath) => ({ id: row.id as string, label: row.name as string, rootPath })); + }); + const remoteProjects = (Array.isArray(stateValue(state, 'remote-projects')) + ? stateValue(state, 'remote-projects') as unknown[] : []).flatMap((value): Project[] => { + const row = record(value); + if (!row || typeof row.id !== 'string' || typeof row.label !== 'string' + || typeof row.remotePath !== 'string' || typeof row.hostId !== 'string') return []; + return [{ id: row.id, label: row.label, rootPath: row.remotePath, hostId: row.hostId }]; + }); + const assignments = record(stateValue(state, 'thread-project-assignments')) ?? {}; + const hints = record(stateValue(state, 'thread-workspace-root-hints')) ?? {}; + const projectless = new Set(Array.isArray(stateValue(state, 'projectless-thread-ids')) + ? stateValue(state, 'projectless-thread-ids') as string[] : []); + return threads.map((thread) => { + const bare = toAppServerThreadId(thread.threadId) ?? thread.threadId; + const assignment = record(assignments[bare]); + const remote = thread.location === 'remote'; + const projects = remote ? remoteProjects.filter((project) => project.hostId === thread.hostId) : localProjects; + let project = assignment && typeof assignment.projectId === 'string' + ? projects.find((entry) => entry.id === assignment.projectId) : undefined; + if (!project && !projectless.has(bare) && thread.projectId) { + project = projects.find((entry) => entry.id === thread.projectId); + } + if (!project && !assignment && !projectless.has(bare)) { + const path = typeof hints[bare] === 'string' ? hints[bare] as string + : typeof thread.cwd === 'string' ? thread.cwd : null; + if (path) project = projects.filter((entry) => pathWithin(path, entry.rootPath)) + .sort((a, b) => b.rootPath.length - a.rootPath.length)[0]; + } + if (project) return { ...thread, project: project.label, projectId: project.id, + projectRootPath: project.rootPath }; + if (projectless.has(bare)) return { ...thread, project: null, projectId: null }; + if (remote && typeof thread.project === 'string' && thread.project.startsWith('/')) { + return { ...thread, project: null }; + } + return thread; + }); +} diff --git a/src/core/chatgpt-desktop/types.ts b/src/core/chatgpt-desktop/types.ts index b0716a1..e807c4b 100644 --- a/src/core/chatgpt-desktop/types.ts +++ b/src/core/chatgpt-desktop/types.ts @@ -25,7 +25,8 @@ export type ChatGptDesktopThread = { readonly selected: boolean; readonly kind: string; /** Project folder name when known (CDP sidebar or app-server projectId). */ - readonly project?: string; + readonly project?: string | null; + readonly projectRootPath?: string; readonly preview?: string; readonly previewTruncated?: boolean; readonly cwd?: string | null; diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx index 30fc7ac..a19eead 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop list threads', description: - 'List Desktop threads, then pass nextCursor as cursor until null. Pages may stop early at the MCP byte budget. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or project label/projectId. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', + 'List one sorted Desktop inventory without duplicate rows. Pass nextCursor as cursor with unchanged filters until null; pages fill limit unless the MCP byte budget binds. A changed/expired inventory cursor requires restarting. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or Desktop project label/projectId; projectRootPath identifies the resolved workspace. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.', annotations: { readOnlyHint: true }, inputSchema, resultSchema, diff --git a/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx b/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx index 4cc5b05..a9804d7 100644 --- a/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx +++ b/src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx @@ -13,7 +13,7 @@ export default defineTool( { title: 'ChatGPT Desktop send', description: - 'Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.', + 'Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. The empty view and project scope are checked before typing. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. PROJECT_UNAVAILABLE identifies a disabled project action or missing configured root; NEW_CHAT_NAVIGATION_FAILED reports an unchanged view promptly. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.', annotations: { readOnlyHint: false }, inputSchema, resultSchema, diff --git a/src/skills/chatgpt-desktop/SKILL.md b/src/skills/chatgpt-desktop/SKILL.md index 5c32b3b..1306013 100644 --- a/src/skills/chatgpt-desktop/SKILL.md +++ b/src/skills/chatgpt-desktop/SKILL.md @@ -19,7 +19,11 @@ another machine. host name from a project label. Managed SSH hosts may have no threads. 3. Use `chatgpt_desktop_list_threads` with `host`, `modelProvider`, or `project` as needed. Pass `nextCursor` back as `cursor` with the same filters until it - is `null`. Pages can stop before `limit` to stay under the MCP document cap. + is `null`. The cursor refers to a sorted merged inventory; pages normally + fill `limit` and can stop earlier at the MCP document cap. If the inventory + changed after a cursor expired, restart without one. Project labels and IDs + come from Desktop project assignments and workspace roots; `projectRootPath` + is the resolved root when available. `chatgpt_desktop_search_threads` also accepts `cursor`; keep its query and filters unchanged. Search matches the full title even when the display row has a 200-character `title` and `titleTruncated: true`. @@ -45,7 +49,8 @@ or app-server. The local Mac cannot fetch that remote history through CDP. thread remains readable through `chatgpt_desktop_read_thread`. - `chatgpt_desktop_send` with `threadId` sends to that conversation. Omit `threadId` and `project` to start outside a project. Omit `threadId` and set - `project` to start inside that project. Send once. A new-thread receipt may + `project` to start inside that project. The tool verifies the empty new-chat + view and its project selection before typing. Send once. A new-thread receipt may include `temporaryThreadId` and resolves `threadId` to the durable `local:` before returning. Keep both until the durable ID is confirmed; use the durable ID for later work. @@ -59,7 +64,11 @@ the user wants the archive state changed; this explicitly calls app-server `thread/unarchive` and retries once. Never unarchive merely to read or open. `COMPOSER_HAS_DRAFT` means the user's draft would be disturbed; leave it for -the operator. `CDP_UNREACHABLE` requires restoring the local Desktop CDP +the operator. `PROJECT_UNAVAILABLE` means Desktop disabled a project's new-chat +action, often because its configured workspace root no longer exists; correct +the project root in Desktop before retrying. `NEW_CHAT_NAVIGATION_FAILED` means +the button did not open the requested empty view within three seconds; inspect +Desktop before retrying. `CDP_UNREACHABLE` requires restoring the local Desktop CDP endpoint. App-server failures, including oversized frames, appear as errors or read `warnings` with `complete: false`; inspect the partial result and source status before continuing. A send with unknown delivery must not be repeated diff --git a/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts b/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts index 622ff35..5f406cd 100644 --- a/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts +++ b/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts @@ -7,7 +7,8 @@ import { listDiscoveredHosts, listRemoteThreadsFromState } from '../../src/core/ import { ChatGptDesktopFacade, finalizeThreadList } from '../../src/core/chatgpt-desktop/facade.js'; import { appServerListThreads, appServerReadThread, appServerSearchThreads, discoverModelProviders } from '../../src/core/chatgpt-desktop/app-server-fallback.js'; import { DESKTOP_RESULT_BUDGET_BYTES, serializedBytes } from '../../src/core/chatgpt-desktop/payload-budget.js'; -import { ARCHIVED_THREAD_EXPRESSION, CONVERSATION_ID_EXPRESSION, LOADING_TASK_GONE_EXPRESSION, navigateToThreadExpression, openThreadInDom, readTurnsFromDom, startNewChatExpression, startNewChatInDom, waitForLoadingTaskGone } from '../../src/core/chatgpt-desktop/cdp-dom.js'; +import { findLocalProject, resolveThreadProjects } from '../../src/core/chatgpt-desktop/project-state.js'; +import { ARCHIVED_THREAD_EXPRESSION, CLEAR_NEW_CHAT_PROJECT_EXPRESSION, CONVERSATION_ID_EXPRESSION, LOADING_TASK_GONE_EXPRESSION, navigateToThreadExpression, openThreadInDom, readTurnsFromDom, startNewChatExpression, startNewChatInDom, waitForLoadingTaskGone } from '../../src/core/chatgpt-desktop/cdp-dom.js'; import { listThreadsOperation, listThreadsSchema, readThreadOperation, readThreadSchema, searchThreadsSchema, statusOperation } from '../../src/core/chatgpt-desktop/routes.js'; import { setChatGptDesktopAdapterForTests } from '../../src/core/chatgpt-desktop/facade.js'; import type { ChatGptDesktopAdapter } from '../../src/core/chatgpt-desktop/adapter.js'; @@ -52,16 +53,51 @@ it('filters thread rows by dynamic project label or projectId', () => { expect(finalizeThreadList(base, { limit: 10, project: 'project-2', remotes: [] }).threads.map((thread) => thread.threadId)).toEqual(['local:two']); }); +it('resolves local and remote project labels from assignments, root hints, and cwd', () => { + const home = mkdtempSync(join(tmpdir(), 'gbot-project-state-')); + try { + writeFileSync(join(home, '.codex-global-state.json'), JSON.stringify({ + 'electron-persisted-atom-state': { + 'local-projects': { core: { id: 'core-id', name: 'core', rootPaths: ['/work/core'] }, + lra: { id: 'lra-id', name: 'codex-lra', rootPaths: ['/work/lra'] } }, + 'remote-projects': [{ id: 'remote-id', hostId: 'remote-host', remotePath: '/fast/core', label: 'remote-core' }], + 'thread-project-assignments': { assigned: { projectKind: 'local', projectId: 'core-id' }, + remote: { projectKind: 'remote', projectId: 'remote-id', hostId: 'remote-host' } }, + 'thread-workspace-root-hints': { hinted: '/work/lra/subfolder' }, + 'projectless-thread-ids': ['projectless'], + }, + })); + const row = (id: string, cwd: string) => ({ threadId: `local:${id}`, title: id, cwd, + pinned: false, selected: false, kind: 'codex' }); + const rows = resolveThreadProjects([row('assigned', '/elsewhere'), row('hinted', '/elsewhere'), + row('cwd', '/work/core/subfolder'), row('projectless', '/work/core'), + { ...row('remote', '/fast/core/subfolder'), location: 'remote', hostId: 'remote-host', hostName: null, + project: '/fast/core/subfolder' }], { CODEX_HOME: home }); + expect(rows.map((thread) => [thread.project, thread.projectId])).toEqual([ + ['core', 'core-id'], ['codex-lra', 'lra-id'], ['core', 'core-id'], [null, null], ['remote-core', 'remote-id'], + ]); + expect(rows[0].projectRootPath).toBe('/work/core'); + expect(findLocalProject('codex-lra', { CODEX_HOME: home })).toMatchObject({ id: 'lra-id', rootPaths: ['/work/lra'] }); + const filtered = finalizeThreadList({ backend: 'app-server', limit: 10, threads: rows }, + { limit: 10, project: 'core', remotes: [] }); + expect(filtered.threads.map((thread) => thread.threadId)).toEqual(['local:assigned', 'local:cwd', 'local:remote']); + expect(finalizeThreadList({ backend: 'app-server', limit: 10, threads: rows }, + { limit: 10, project: 'lra-id', remotes: [] }).threads.map((thread) => thread.threadId)).toEqual(['local:hinted']); + } finally { rmSync(home, { recursive: true, force: true }); } +}); + it('counts CDP-only remote rows in host discovery', async () => { const row = { threadId: 'local:cdp-only', title: 'remote', pinned: false, selected: false, kind: 'remote', location: 'remote' as const, hostId: 'remote:dynamic', hostName: null }; + const local = { threadId: 'local:local-cdp-only', title: 'local', pinned: false, selected: false, kind: 'codex', location: 'local' as const }; const facade = new ChatGptDesktopFacade({ - connect: async () => {}, listThreads: async () => ({ backend: 'cdp', limit: 200, threads: [row] }), + connect: async () => {}, listThreads: async () => ({ backend: 'cdp', limit: 200, threads: [row, local] }), } as unknown as ChatGptDesktopAdapter, 9222, { listThreads: async () => ({ backend: 'app-server', limit: 25, threads: [] }), listRemoteThreads: () => [], listHosts: () => [{ hostId: 'local', hostName: 'local', location: 'local', threadCount: 0 }], discoverModelProviders: async () => ({ providers: [], source: 'thread/list-distinct', threadCount: 0, complete: true }), } as never); expect((await facade.listHosts()).hosts).toEqual(expect.arrayContaining([expect.objectContaining({ hostId: 'remote:dynamic', threadCount: 1 })])); + expect((await facade.listHosts()).hosts.find((host) => host.hostId === 'local')?.threadCount).toBe(1); }); it('uses the same deduplicated remote rows for host count and host-filtered list', async () => { @@ -89,7 +125,7 @@ it('surfaces provider discovery errors with the remote fallback', async () => { listRemoteThreads: () => [], listHosts: () => [], discoverModelProviders: async () => { throw new Error('frame too large'); }, } as never); - expect((await facade.listHosts()).warnings).toEqual(['Model provider discovery failed: frame too large']); + expect((await facade.listHosts()).warnings).toEqual(expect.arrayContaining(['Model provider discovery failed: frame too large'])); }); it('uses small app-server pages for provider discovery and search', async () => { @@ -259,56 +295,60 @@ it('marks a CDP read partial and preserves the app-server failure', async () => }); }); -it('passes the opaque list cursor through facade and route', async () => { +it('pages one sorted merged inventory exactly once across app, CDP and remote rows', async () => { + const row = (id: string, updatedAt: number) => ({ threadId: `local:${id}`, title: id, + updatedAt, pinned: false, selected: false, kind: 'codex' }); + const app = [row('a', 900), row('b', 800), row('c', 700), row('d', 600), row('e', 500), row('f', 400)]; + const cdp = [{ ...row('a', 900), selected: true }, { ...row('c', 700), location: 'remote' as const, hostId: 'host', hostName: null }, row('sidebar-only', 550)]; + const remote = [{ ...row('c', 700), location: 'remote' as const, hostId: 'host', hostName: null }, + { ...row('remote-only', 750), location: 'remote' as const, hostId: 'host', hostName: null }]; const calls: unknown[] = []; - const facade = new ChatGptDesktopFacade({ connect: async () => { throw new Error('offline'); } } as unknown as ChatGptDesktopAdapter, 9222, { - listThreads: async (options: { cursor?: string; limit?: number }) => { calls.push(options.cursor); return { backend: 'app-server', limit: options.limit ?? 50, nextCursor: 'next-page', threads: [] }; }, - listRemoteThreads: () => [], - } as never); - expect((await facade.listThreads({ cursor: 'previous' })).nextCursor).toBe('next-page'); - expect(calls).toEqual(['previous']); - expect(listThreadsSchema.parse({ cursor: 'previous' }).cursor).toBe('previous'); - setChatGptDesktopAdapterForTests({ connect: async () => {}, close: async () => {}, listThreads: async (options: { cursor?: string } = {}) => ({ backend: 'app-server', limit: 1, nextCursor: options.cursor, threads: [] }) } as unknown as ChatGptDesktopAdapter); - expect(await listThreadsOperation(listThreadsSchema.parse({ cursor: 'previous' }))).toMatchObject({ nextCursor: 'previous', exitCode: 0 }); -}); - -it('reserves first-page space for remote rows without skipping local cursor rows', async () => { - const row = (id: string) => ({ threadId: `local:${id}`, title: id, pinned: false, selected: false, kind: 'codex' }); - const appCalls: Array<{ limit?: number; cursor?: string }> = []; - const facade = new ChatGptDesktopFacade({ - connect: async () => {}, - listThreads: async () => ({ backend: 'cdp', limit: 5, threads: [{ ...row('cdp-remote'), location: 'remote', hostId: 'host', hostName: null }] }), - } as unknown as ChatGptDesktopAdapter, 9222, { - listThreads: async (options: { limit?: number; cursor?: string }) => { - appCalls.push(options); - const start = Number(options.cursor ?? 0); - const count = options.limit ?? 5; - return { backend: 'app-server', limit: count, nextCursor: String(start + count), - threads: Array.from({ length: count }, (_, i) => row(`local-${start + i}`)) }; + const facade = new ChatGptDesktopFacade({ connect: async () => {}, + listThreads: async () => ({ backend: 'cdp', limit: 200, threads: cdp }) } as unknown as ChatGptDesktopAdapter, 9222, { + listThreads: async ({ cursor }: { cursor?: string }) => { + calls.push(cursor); + const offset = Number(cursor ?? 0); + return { backend: 'app-server', limit: 200, threads: app.slice(offset, offset + 2), + nextCursor: offset + 2 < app.length ? String(offset + 2) : null }; }, - listRemoteThreads: () => [{ ...row('state-remote'), location: 'remote', hostId: 'host', hostName: null }], + listRemoteThreads: () => remote, } as never); - const first = await facade.listThreads({ limit: 5 }); - const second = await facade.listThreads({ limit: 5, cursor: first.nextCursor! }); - expect(first.threads).toHaveLength(5); - expect(first.threads.filter((thread) => thread.location === 'remote')).toHaveLength(2); - expect(appCalls).toMatchObject([{ limit: 3 }, { limit: 5, cursor: '3' }]); - expect(second.threads[0].threadId).toBe('local:local-3'); + const pages = []; + let cursor: string | null | undefined; + do { + const out = await facade.listThreads({ limit: 3, ...(cursor ? { cursor } : {}) }); + pages.push(out); + cursor = out.nextCursor; + } while (cursor); + expect(pages.map((page) => page.threads.length)).toEqual([3, 3, 2]); + expect(pages.flatMap((page) => page.threads.map((thread) => thread.threadId))).toEqual([ + 'local:a', 'local:b', 'local:remote-only', 'local:c', 'local:d', 'local:sidebar-only', 'local:e', 'local:f', + ]); + expect(pages[1].threads.find((thread) => thread.threadId === 'local:c')?.location).toBe('remote'); + expect(calls).toEqual([undefined, '2', '4']); + await expect(facade.listThreads({ limit: 3, cursor: pages[0].nextCursor!, host: 'local' })).rejects.toThrow('filters'); + expect(listThreadsSchema.parse({ cursor: pages[0].nextCursor }).cursor).toBe(pages[0].nextCursor); + setChatGptDesktopAdapterForTests({ connect: async () => {}, close: async () => {}, + listThreads: async (options: { cursor?: string } = {}) => ({ backend: 'app-server', limit: 1, nextCursor: options.cursor, threads: [] }) } as unknown as ChatGptDesktopAdapter); + expect(await listThreadsOperation(listThreadsSchema.parse({ cursor: pages[0].nextCursor }))).toMatchObject({ nextCursor: pages[0].nextCursor, exitCode: 0 }); }); -it('pages remote rows before local rows when the page is smaller than remote inventory', async () => { - const row = (id: string) => ({ threadId: `local:${id}`, title: id, pinned: false, selected: false, kind: 'remote', location: 'remote' as const, hostId: 'host', hostName: null }); - const facade = new ChatGptDesktopFacade({ connect: async () => {}, listThreads: async () => ({ backend: 'cdp', limit: 200, threads: [] }) } as unknown as ChatGptDesktopAdapter, 9222, { - listThreads: async ({ cursor }: { cursor?: string }) => ({ backend: 'app-server', limit: 1, nextCursor: null, - threads: [{ threadId: `local:${cursor ? 'next' : 'first'}`, title: 'local', pinned: false, selected: false, kind: 'codex' }] }), - listRemoteThreads: () => [row('remote-a'), row('remote-b')], - } as never); - const first = await facade.listThreads({ limit: 1 }); - const second = await facade.listThreads({ limit: 1, cursor: first.nextCursor! }); - const third = await facade.listThreads({ limit: 1, cursor: second.nextCursor! }); - expect(first.threads[0].threadId).toBe('local:remote-a'); - expect(second.threads[0].threadId).toBe('local:remote-b'); - expect(third.threads[0].threadId).toBe('local:first'); +it('fills a 100-row app-server page using bounded 25-row RPC requests', async () => { + const bridge = await import('../../src/core/codex-bridge.js'); + const limits: number[] = []; + rstest.spyOn(bridge, 'listCodexThreads').mockImplementation(async ({ limit, cursor } = {}) => { + limits.push(limit!); + const offset = Number(cursor ?? 0); + return { limit: limit!, threads: Array.from({ length: Math.min(limit!, 120 - offset) }, (_, i) => ({ + id: `id-${offset + i}`, name: `title-${offset + i}` })), + nextCursor: offset + limit! < 120 ? String(offset + limit!) : null } as never; + }); + const first = await appServerListThreads({ limit: 100 }); + const second = await appServerListThreads({ limit: 100, cursor: first.nextCursor! }); + expect([first.threads.length, second.threads.length]).toEqual([100, 20]); + expect([...first.threads, ...second.threads].map((row) => row.threadId)).toEqual( + Array.from({ length: 120 }, (_, i) => `local:id-${i}`)); + expect(limits).toEqual([25, 25, 25, 25, 25]); }); it('reports CDP unreachable even when app-server is reachable', async () => { @@ -323,7 +363,8 @@ it('hovers then dispatches a real project button press and release', async () => const sent: string[] = []; const session = { evaluate: async (expression: string) => expression.includes('getComputedStyle') - ? { x: 12, y: 14, visible: true } + ? { x: 12, y: 14, visible: true, disabled: false } + : expression.includes('const expected =') ? { ready: true, path: '/', composer: true, scope: 'Change project: core' } : { ok: true, via: 'project', hoverX: 8, hoverY: 10 }, send: async (_method: string, params: { type: string }) => { sent.push(params.type); }, }; @@ -331,6 +372,32 @@ it('hovers then dispatches a real project button press and release', async () => expect(sent).toEqual(['mouseMoved', 'mouseMoved', 'mousePressed', 'mouseReleased']); }); +it('rejects a disabled project action before sending and reports a failed navigation quickly', async () => { + const sent: string[] = []; + const disabled = { evaluate: async () => ({ ok: true, via: 'project', disabled: true, hoverX: 8, hoverY: 10 }), + send: async (method: string) => { sent.push(method); } }; + await expect(startNewChatInDom(disabled as never, 'page', { project: 'missing-root' })).rejects.toMatchObject({ code: 'PROJECT_UNAVAILABLE' }); + expect(sent).toEqual([]); + const noNavigation = { evaluate: async (expression: string) => expression.includes('const expected =') + ? { ready: false, path: '/local/old', composer: false, scope: '' } + : expression.includes('getComputedStyle') ? { x: 12, y: 14, visible: true, disabled: false } + : { ok: true, via: 'project', hoverX: 8, hoverY: 10 }, send: async () => {} }; + await expect(startNewChatInDom(noNavigation as never, 'page', { project: 'core', navigationTimeoutMs: 20 })) + .rejects.toMatchObject({ code: 'NEW_CHAT_NAVIGATION_FAILED' }); +}); + +it('clears a retained project before treating a new chat as projectless', async () => { + let cleared = false; + const session = { evaluate: async (expression: string) => { + if (expression === CLEAR_NEW_CHAT_PROJECT_EXPRESSION) { cleared = true; return true; } + if (expression.includes('const expected =')) return { ready: cleared, path: '/', composer: true, + scope: cleared ? 'Choose project' : 'Change project: core' }; + return { ok: true, via: 'fallback' }; + } }; + expect(await startNewChatInDom(session as never, 'page')).toEqual({ via: 'fallback' }); + expect(cleared).toBe(true); +}); + it('uses the displayed durable id before sidebar lookup and routes missing rows', async () => { const expressions: string[] = []; const session = { evaluate: async (expression: string) => { diff --git a/tests/route-unit/chatgpt-desktop-mcp-followup.test.ts b/tests/route-unit/chatgpt-desktop-mcp-followup.test.ts index b8c34f8..5ccae37 100644 --- a/tests/route-unit/chatgpt-desktop-mcp-followup.test.ts +++ b/tests/route-unit/chatgpt-desktop-mcp-followup.test.ts @@ -1,3 +1,6 @@ +import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; import { afterEach, expect, it, rstest } from '@rstest/core'; import { invokeMcpTool, listMcpSurface } from 'agent-bundle/test'; import { CdpSession } from '../../src/core/chatgpt-desktop/cdp-session.js'; @@ -105,7 +108,8 @@ it('returns a durable id after one new-thread-in-project send while preserving t const events: string[] = []; mockCdp((expression) => { if (expression.includes('projectSel')) return { ok: true, via: 'project', hoverX: 8, hoverY: 10 }; - if (expression.includes('getComputedStyle')) return { x: 12, y: 14, visible: true }; + if (expression.includes('getComputedStyle')) return { x: 12, y: 14, visible: true, disabled: false }; + if (expression.includes('const expected =')) return { ready: true, path: '/', composer: true, scope: 'Change project: core' }; if (expression === LOADING_TASK_GONE_EXPRESSION) return true; if (expression === CONVERSATION_ID_EXPRESSION) return submitted ? 'durable-conversation' : ''; if (expression === LIST_THREADS_EXPRESSION) return [{ threadId: 'local:client-new-thread:temporary', title: 'new', selected: true, pinned: false, kind: 'local' }]; @@ -128,6 +132,30 @@ it('returns a durable id after one new-thread-in-project send while preserving t expect(events.filter((event) => event === 'keyUp')).toHaveLength(1); }); +it('rejects a project whose configured root is missing before touching the composer', async () => { + const home = mkdtempSync(join(tmpdir(), 'gbot-unavailable-project-')); + const previous = process.env.CODEX_HOME; + let inserted = false; + try { + writeFileSync(join(home, '.codex-global-state.json'), JSON.stringify({ + 'electron-persisted-atom-state': { 'local-projects': { + missing: { id: 'missing', name: 'missing-project', rootPaths: ['/no/such/project/root'] }, + } }, + })); + process.env.CODEX_HOME = home; + mockCdp(() => false, (method) => { if (method === 'Input.insertText') inserted = true; }); + const adapter = new CdpChatGptDesktopAdapter(); + await adapter.connect({ port: 9222 }); + await expect(adapter.sendMessage({ project: 'missing-project', text: 'must not send' })) + .rejects.toMatchObject({ code: 'PROJECT_UNAVAILABLE', delivery: 'rejected' }); + expect(inserted).toBe(false); + } finally { + if (previous === undefined) delete process.env.CODEX_HOME; + else process.env.CODEX_HOME = previous; + rmSync(home, { recursive: true, force: true }); + } +}); + it('passes the dynamic project filter through the MCP list contract', async () => { const calls: string[] = []; setChatGptDesktopAdapterForTests({ diff --git a/tests/route-unit/chatgpt-desktop.test.ts b/tests/route-unit/chatgpt-desktop.test.ts index 9b51797..1bfce30 100644 --- a/tests/route-unit/chatgpt-desktop.test.ts +++ b/tests/route-unit/chatgpt-desktop.test.ts @@ -660,9 +660,9 @@ describe('chatgpt-desktop app-server list/read/search + CDP-only send/wait', () expect(opened).toMatchObject({ backend: 'cdp' }); expect(calls).toEqual([ + 'app-server.listThreads', 'cdp.connect', 'cdp.listThreads', - 'app-server.listThreads', 'app-server.searchThreads', 'cdp.listThreads', 'app-server.readThread', From 94b283cf20ec3f126839727ffc3ad7a4d00aa866 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 28 Sep 2026 23:10:56 -0700 Subject: [PATCH 26/26] fix: address Codex review of Desktop search, read fallback and backend provenance --- artifact/agent-bundle.compile-evidence.json | 2 +- artifact/agent-bundle.manifest.json | 2 +- artifact/bin/gbot-flight.mjs | 213 +++++++++++------- artifact/bin/gbot.mjs | 213 +++++++++++------- artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs | 213 +++++++++++------- artifact/mcp/mcp-grok-bot-b8c2461e.mjs | 213 +++++++++++------- .../chatgpt-desktop/app-server-fallback.ts | 2 +- src/core/chatgpt-desktop/facade.ts | 176 +++++++++------ .../chatgpt-desktop-e2e-regressions.test.ts | 60 +++++ 9 files changed, 706 insertions(+), 388 deletions(-) diff --git a/artifact/agent-bundle.compile-evidence.json b/artifact/agent-bundle.compile-evidence.json index d6e9baa..19df1e0 100644 --- a/artifact/agent-bundle.compile-evidence.json +++ b/artifact/agent-bundle.compile-evidence.json @@ -1 +1 @@ -{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/facade.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"4aeefdb20d12412c6b2aa60267adc1cab7d9bec983bc14842f24eec4356aba9d"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/chatgpt-desktop/facade.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"8909903b828c9ee383517f3e8c621536fd1ebdf95ece636f2a19fa0101602496"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"3a966160704621cd614ae9217051b2a681c0c913dd7507020c71c79f02161486"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/facade.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"6e2ae3edd0f2fa384effd01206c779b79b4ac1c86aaa336dd68521bfc0cba89c"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/chatgpt-desktop/facade.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"3ec354d5588fe43916dc82f42b035c52c79170a9fbdef43ee330fe7c44664194"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"faf9fe6e3f82f9ae4a7ea61d04c2099c98057e325888e8769aa552b339c046cb"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} +{"assets":[{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/facade.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot-flight.mjs","sha256":"b0a314b26965679b91a06be788337603c12006f3061beebb5f4a682e6e26a581"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/cli/codex/bridge/run.tsx","src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/667~1.js","src/core/app-session.js","src/core/chatgpt-desktop/facade.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/cli/skills/add.tsx","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/cli/skills/add.tsx","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/history.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/history.js"],"kind":"builtin","request":"node:readline","userRequest":"node:readline"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-0.mjs",".agent-bundle-virtual/bin-gbot-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/bin-gbot-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"bin/gbot.mjs","sha256":"1da1b6468f12930e44b9be5422ada37905e0ea0a558569d98d8da17df9e2362f"},{"externals":[{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/claude-channel.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/launch-env.js","src/core/claude-channel.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs","node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-claude-channel-8029413c-1.mjs"],"kind":"builtin","request":"node:url","userRequest":"node:url"}],"packages":["@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","zod"],"path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"3a966160704621cd614ae9217051b2a681c0c913dd7507020c71c79f02161486"},{"externals":[{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"async_hooks","userRequest":"async_hooks"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"crypto","userRequest":"crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/facade.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-flight-entry.mjs"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"stream","userRequest":"stream"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-server.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"0c9ab3f71ae43f71263cae3d55b241e731ae663ecbe580c31e3a50d63e3a3a3d"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/@agent-bundle/runtime/dist/lineage.js","node_modules/agent-bundle/dist/667~1.js","node_modules/agent-bundle/dist/mcp-server-runtime.js","src/core/app-session.js","src/core/chatgpt-desktop/facade.ts","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","node_modules/agent-bundle/dist/terminal-capability.js","src/core/app-session.js","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/40.js","node_modules/agent-bundle/dist/667~1.js","src/core/claude-channel.js","src/core/relay/managed.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/claude-channel.js","src/core/codex-bridge.js","src/core/relay/control.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/49.js","node_modules/agent-bundle/dist/launch-env.js","src/core/app-session.js","src/core/claude-channel.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"module","issuers":["node_modules/agent-bundle/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs"],"kind":"builtin","request":"node:process","userRequest":"node:process"},{"externalType":"module","issuers":["src/core/relay/control.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"},{"externalType":"module","issuers":[".agent-bundle-virtual/mcp-grok-bot-b8c2461e-1.mjs",".agent-bundle-virtual/mcp-grok-bot-b8c2461e-2.mjs","src/core/relay/managed.js"],"kind":"builtin","request":"node:url","userRequest":"node:url"},{"externalType":"module","issuers":["node_modules/agent-bundle/dist/mcp-server-runtime.js"],"kind":"builtin","request":"node:worker_threads","userRequest":"node:worker_threads"},{"externalType":"node-commonjs","issuers":["node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.development.js","node_modules/react-server-dom-rspack/cjs/react-server-dom-rspack-client.node.production.js"],"kind":"builtin","request":"util","userRequest":"util"}],"packages":["@agent-bundle/runtime","@modelcontextprotocol/core","@modelcontextprotocol/server","agent-bundle","effect","react","react-dom","react-server-dom-rspack","rsc-markdown-stream","zod"],"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"44bb2d1883bb081e78d216914a6adcb54b5d2d3ddb811f52bb486dcee63c6fd7"},{"externals":[{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state.js"],"kind":"builtin","request":"node:assert/strict","userRequest":"node:assert/strict"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/736.js"],"kind":"builtin","request":"node:async_hooks","userRequest":"node:async_hooks"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/302.js"],"kind":"builtin","request":"node:buffer","userRequest":"node:buffer"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/desktop-shim.js"],"kind":"builtin","request":"node:child_process","userRequest":"node:child_process"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/gateway.js","src/core/relay/codex.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:crypto","userRequest":"node:crypto"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/codex.js","src/core/store.js"],"kind":"builtin","request":"node:fs","userRequest":"node:fs"},{"externalType":"module","issuers":["src/core/relay/ownership.js","src/core/relay/state.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:fs/promises","userRequest":"node:fs/promises"},{"externalType":"module","issuers":["src/core/codex-bridge.js","src/core/relay/control.js","src/core/relay/ownership.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:net","userRequest":"node:net"},{"externalType":"module","issuers":["src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/profile.js","src/core/store.js"],"kind":"builtin","request":"node:os","userRequest":"node:os"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/remote-control.js","src/core/desktop-shim.js","src/core/relay/engine.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/state.js","src/core/store.js"],"kind":"builtin","request":"node:path","userRequest":"node:path"},{"externalType":"import","issuers":["src/core/relay/ownership.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["node_modules/@agent-bundle/runtime/dist/state/sqlite.js"],"kind":"builtin","request":"node:sqlite","userRequest":"node:sqlite"},{"externalType":"module","issuers":["src/core/relay/control.js","src/core/relay/worker.js"],"kind":"builtin","request":"node:string_decoder","userRequest":"node:string_decoder"}],"packages":["@agent-bundle/runtime","effect","zod"],"path":"scripts/gbot-relay.mjs","sha256":"faf9fe6e3f82f9ae4a7ea61d04c2099c98057e325888e8769aa552b339c046cb"}],"coverage":{"rewritable":false,"unobserved":["import()","require()","require.resolve(…)","createRequire(…)(…)","import.meta.resolve(…)"]},"policy":{"name":"closed-world-externals","revision":1},"producer":{"name":"agent-bundle","rspack":"2.2.8","version":"0.3.1"}} diff --git a/artifact/agent-bundle.manifest.json b/artifact/agent-bundle.manifest.json index 03de640..042b022 100644 --- a/artifact/agent-bundle.manifest.json +++ b/artifact/agent-bundle.manifest.json @@ -1 +1 @@ -{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.2"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"b462f5594e8174bb3c565276aa2dcb5f56094d68add7f8b991b09701ed1417a6","packageName":"grok-bot-cli","packageVersion":"0.10.2","revision":"d3cb1cb2af48ebb834a56a0a61122995eaf17be181702494890027c6a529784a","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/desktop-e2e-reliability.md","sha256":"ebb912d56ba3321df13a9d611780129af8f4c264dbc5e841df6c1a8a838dfc10"},{"executable":false,"path":".changeset/desktop-merged-pagination-projects.md","sha256":"686b95a887f227380fce54a4a36c227b8a53b924038ddaad82d1c2a778699168"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"30aaeac24084f0a642d811aa493fc51b0fd3eddff322d359c39c573d8394ff3e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"49d0b5b880153fa7be882f31c8edf73cf04fe0a5f83e2bb880a48ccda495044d"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"6dd6cfe00e9a888c1ced79f1db85744f9c92affef8a78126e22ea5205e76b732"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"42509e8e4c2b519949f06d4e7028b8973d56f8fc0cd98decdb231375bb49d38d"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"4894d2ae20d895b1b213c0bd7eb7a6c483a7ae632e49ffeaa4eb7564bc71abde"},{"executable":false,"path":"README.md","sha256":"efe1a601a87648defca4b223f5b6828ead8f17fc15ad1fb8eeac23b9b61b8b29"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"11c86f604c2ee405f7544394db60ee1b36917d0b90769d441fcd361b5f0fe038"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"0dc3acdea178ff14d6c1c4b8b3bf1e18af47984f63b8ed8c41483e4da4b72f08"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"b801a028980e60fe37dca56e86887a1e2b0b8ce80ce77b379e7375d2e4544d5e"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"d0a33935d992af349c52ef448622da5e460b4af1a9474aac60994295245b43ad"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/new.tsx","sha256":"11d0658c1a3e7173d53b71446b184fccccd867baefc6f733e43a9d543ca26ec9"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"a1b30f053a9e65bac561cd04d1361e292e2c672bbf69a6d76d2bdda441c46757"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"0a4cc6c440ad496682031658bda375fee29f5c346d833618d4f143de29b351cd"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/commands/codex-send.md","sha256":"ef29096075a13a28be9c2ee7a6226f169ffd330a7f21698b3927273070a6086d"},{"executable":false,"path":"src/commands/codex-threads.md","sha256":"bacac58bb4e61766ea76f9abad71c25207192bc609ce3bf3f122686c00d674a4"},{"executable":false,"path":"src/commands/codex-wait.md","sha256":"ef224414fe7a9f2aaaae2fba8b83f0600cb3589dfc20920a69b29db3a5f2d880"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5a0a4f2cea9f1fc1a739c534aed3979c28e0bd9c057b8475e6251974ad44ed7a"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"405ba6ccf579016440f3528d3786f52a8e2fbb15f10a70da4cdf374b84db3fee"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"db60fdd3be0259a6c76cad7d8ff86eddc6acbbd21c5f20d6aeffff5390063efa"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"a122fb76626006fa8dedb7088f9b5533a8058c3a58838692b168e0753b7c89eb"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"941ce4a9148fc53086cce64336dba473c1f7e4138774fd50a8ae524dcc05d34d"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"992aa3f5196f00d2c2267383d2eb00d18b2b39e503f41255da1d7911d58574ee"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"591e6968c008cc75827da94b91c0ea15e573640876814e35e2470342dc8bccf9"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/payload-budget.ts","sha256":"89410474315b3769bad58d3ab61999e169410b7d1fdc20819efb4ee9c82fe1ac"},{"executable":false,"path":"src/core/chatgpt-desktop/project-state.ts","sha256":"b33e55b6d6abf15f3d7d1489b8b178d4e907ea83ed1a47d88f8f178a574709f8"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"ed93418ff5d2bb51016783e7b0a458805e709b212974a66be804ddb9f7038033"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"ccf8cde780da6e6e03f11e4dcc0d9d6bc4a6a3fd20d3210e74f0217e3660b7e1"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"59f89694eed34206e32db2a0afb48670bb164a4ffffacb907c8629bb0ce4bcca"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"78f0fbba7a5053eb78717c5885a9306871f08beaf39da90df1f815a66b1288d9"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"05abb2253480d0793bf5f6b3db17c47e7d154973747074c7c76a79e6f61b7deb"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"52565007799e98c3bff4297287d8e53005e285a95bab9e4e4d0a088bded4fa8e"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"ae29d05e06cdd8e90bcdd723d277af748e16dc676db1e4b938b7cdd36340ed17"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"ff6e8f3158d171911a35b829cd76e1f5fd8319f8143f727a4854448fc09edeec"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"5b80f7dfe7e438811d9f27c1f9038d7631f8c73266d2ec7b1108c1ce9ecbbb47"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"4007e9908e285036786b7b0291dd480d03d51ad03f973fa578444accffa1f416"},{"executable":false,"path":"src/core/relay/state.js","sha256":"c18eda2f956944d0f318910de5239b954090eab81f7c77b4683e326a6d34b2b8"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"c8409ae9679246d8f907f1e0d16ec1c415d6697f2ce048fb64a599734486b9a6"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"86334421686350ea044fb1160c19b6f5889425feb78fd608675feb8137492090"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"5f24cfdace92522891dfbaed0bd90e74b7de6bb8d193e0ef3bd5582c05a06914"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","sha256":"b415d5bd303693649abae96b6b9d2920d29c797f5367ae8fbb2b62b635528e37"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"6adc4318f4b6c90b1d3970046266197348f79757c0d52ffe991d6338eb1fed6c"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"1d50db88cf7d06a74524c8937ed9045eaaf2560f6766d6c411b3bb55575d1d3f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"9e1b93735b9a38216c7e9aac4c5b62bc2ac20b60e1979a19c4610f0208961af5"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"681e50ae6c7d3a04a76ad8eadf865ab9d793b5eb3c78f961a42d0902adacc306"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"2786b62ff2a1a4e68229199935ac63c15614a0f0bdbef74b2d06e0c405516272"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_new.tsx","sha256":"556c8d6f5f2b07b20e9daae7aa8008ee3775582a4d034415fc86fecda0c63866"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"5c02dc335a0354850d05e5827f6124d0ddc08b9b654059984887c55e4cd778c9"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"cb08b094860f3a09c937eb8339108015fe0de57d9f6c6886aea2028cd33ef207"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/chatgpt-desktop/SKILL.md","sha256":"0fe2560037f761203a317bf8755b0476ce864b7b1b13708559448d300aa4635c"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"55a1afcdea07f325b3528dd0c546ecc4cbfd6069610ecc4f773f049cd597e69c"},{"executable":false,"path":"test/codex-commands.test.js","sha256":"ab15a53a76eb82dc9c51c9fabd0affd2a1037cde27765fef08ecd0012a2e4495"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"789d0245a8d470860f7535c6ef3849313205097f6df517ab9946e47a789f8534"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"fa44f15f46d0cae486c13be3fae09568f17f8581001ec50a61478bec03f4c28c"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a8c06138d895ffaa30476f3a2ddf1ef50ef73a816a665f749f451d01d9cc2551"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts","sha256":"b1a5818fc873c318e9978c92dd75b97f995fa6871a88cef6d90ab6e8d439e39e"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-mcp-followup.test.ts","sha256":"4a2db11a642b8daef05285f096ce026ca5b9b6394c31c0966d7e5f8c1d49f4ca"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"208dfdea18ccc408a279666a521d2f70fdce9bdaf28f86bc5d053f7ad09a7dd2"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"5cf61e174b1d4a7c0f2209d6746bb1880a96fe550f7d2c4ea94e849dd7f21299"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7c7d971edaa7ef134d0dfba12208f88ec7f69c11dca79ad61d6e6cfae6d34c43"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/commands/codex-send.md","src/commands/codex-threads.md","src/commands/codex-wait.md","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/new.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/project-state.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/new.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/project-state.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"commands/codex-send.md","sourceInputs":["src/commands/codex-send.md"]},{"path":"commands/codex-threads.md","sourceInputs":["src/commands/codex-threads.md"]},{"path":"commands/codex-wait.md","sourceInputs":["src/commands/codex-wait.md"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/project-state.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_new.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/project-state.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_new.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/chatgpt-desktop/SKILL.md","sourceInputs":["src/skills/chatgpt-desktop/SKILL.md"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"a8f5bf1f109d8f88b4195f3baea389e942af2f0ef544ecc22502326bcf3e742e"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"1420b97dfe289c97c24e855ba758439c94fa0e92aa38aae467312fbe341d5d15"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"a3ab79672b9ab74affae23c25ef06ddc926da90d0ff2499e9471c3e4c6ba475f"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":694,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"12321577920803f3d60bf071167f8b7888d94d720d06c5caa38f3b30c8bfda73"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22592,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"7ed7f3f8f44939f00966c0ee2f89a2a8c95bdf3b63bea7d976a1a9414df034d8"},{"bytes":1588943,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"4aeefdb20d12412c6b2aa60267adc1cab7d9bec983bc14842f24eec4356aba9d"},{"bytes":2459321,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"8909903b828c9ee383517f3e8c621536fd1ebdf95ece636f2a19fa0101602496"},{"bytes":290,"kind":"generated","path":"commands/codex-send.md","sha256":"6d188a21596115f4aa65e39718cede5eff837749c8652a12e2a5b25d8a3e0ef3"},{"bytes":195,"kind":"generated","path":"commands/codex-threads.md","sha256":"0db562fff831ede9dd300552aecc5b29d347c94ebeb3df9f488cb1a87b990cf8"},{"bytes":205,"kind":"generated","path":"commands/codex-wait.md","sha256":"fb04448a474b2f14ddb59739d5f79bcf251a3e1136ffe9b3e50ca5654aa6070b"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"5fdafbf8a3fa3d2205e6a308d37deb8ad31910927334a855f70e11977d43f6a9"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"d5c328ca82057cd05b90372a8cfa8ed3e8c6f7f1b14b1f579ae82250722c3d93"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270116,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"3a966160704621cd614ae9217051b2a681c0c913dd7507020c71c79f02161486"},{"bytes":1520465,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"6e2ae3edd0f2fa384effd01206c779b79b4ac1c86aaa336dd68521bfc0cba89c"},{"bytes":3347922,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"3ec354d5588fe43916dc82f42b035c52c79170a9fbdef43ee330fe7c44664194"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"862f9ff4c106a5b4c3bb09d498a2f395e3450074c8c79525c3a34aa67179d594"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1305648,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"faf9fe6e3f82f9ae4a7ea61d04c2099c98057e325888e8769aa552b339c046cb"},{"bytes":4856,"kind":"copy","path":"skills/chatgpt-desktop/SKILL.md","sha256":"0fe2560037f761203a317bf8755b0476ce864b7b1b13708559448d300aa4635c"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"description":"Opaque nextCursor from the prior read page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Recent default 100; full default 2000","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a prior search page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false},{"description":"Explicitly unarchive an existing archived thread before sending.","key":"unarchive","kind":"boolean","option":"unarchive","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a previous page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"Start a new Codex thread in --cwd, optionally with --model, --effort and a message.","exitCode":"result","options":[{"key":"cwd","kind":"string","option":"cwd","repeated":false,"required":true},{"choices":["none","minimal","low","medium","high","xhigh"],"key":"effort","kind":"enum","option":"effort","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":0,"repeated":true,"required":false},{"key":"model","kind":"string","option":"model","repeated":false,"required":false}],"path":["codex","new"],"routeId":"cli:codex/new"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"choices":["none","minimal","low","medium","high","xhigh"],"key":"effort","kind":"enum","option":"effort","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"model","kind":"string","option":"model","repeated":false,"required":false},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-7200000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-7200000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page","type":"string"},"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a prior search page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/new.tsx#inputJsonSchema","description":"Start a new Codex thread in --cwd, optionally with --model, --effort and a message.","id":"cli:codex/new","inputSchema":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/new.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page","type":"string"},"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a prior search page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/new.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/new.tsx"},"routes":["cli:codex/new"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_open_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page. Keep threadId and full unchanged.","type":"string"},"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the previous search page; keep query and filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_new.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"type":"string"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_new.tsx"},"routes":["tool:grok-bot/codex_new"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"c0f041a6aedf5b5e8760c0125a69225707c642edb094259fa080c580fe89668c","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover local, remote-control environment ids, managed SSH hosts, and modelProvider ids. hostName is null when Desktop has no real display name. Use hostId or label in list/search filters; remote thread ids must be read on the owning host. warnings report provider discovery failures.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List one sorted Desktop inventory without duplicate rows. Pass nextCursor as cursor with unchanged filters until null; pages fill limit unless the MCP byte budget binds. A changed/expired inventory cursor requires restarting. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or Desktop project label/projectId; projectRootPath identifies the resolved workspace. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","description":"Navigate Desktop to an existing local: or bare conversation id, even when the row is absent from the sidebar. Archived routes return archived:true without unarchiving; read them with chatgpt_desktop_read_thread. A remote-control id is owned by its hostId and cannot be opened on this Mac. CDP_UNREACHABLE means Desktop must be reachable locally.","id":"tool:grok-bot/chatgpt_desktop_open_thread","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Pass nextCursor back as cursor with the same threadId/full mode until complete:true. Pages stop at a byte budget; oversized turns use ordered continuation fragments with stable turnKey and field offsets, without dropping text. Archived threads remain readable. Warnings explain partial pages or app-server errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page. Keep threadId and full unchanged.","type":"string"},"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search full Desktop thread metadata by case-insensitive substring. Display titles are capped at 200 characters with titleTruncated:true. Pass nextCursor as cursor with unchanged query and filters to retrieve all matches. Dynamic hostId/hostName, modelProvider, and project filters apply. Remote results identify hostId and cannot be read on this Mac.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the previous search page; keep query and filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. The empty view and project scope are checked before typing. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. PROJECT_UNAVAILABLE identifies a disabled project action or missing configured root; NEW_CHAT_NAVIGATION_FAILED reports an unchanged view promptly. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Check local ChatGPT Desktop CDP before send, wait, or open. reachable:false and exitCode:1 mean CDP is down even if appServerFallback.reachable is true; list/search/read may still work through app-server. There is no remote CDP transport.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"After chatgpt_desktop_send, wait for the selected Desktop reply over CDP. Accept the returned durable local: or the temporary local:client-new-thread:* while selected; omit threadId only when staying on the same selected chat. Returns reply, durable threadId and conversationId. timeout is not proof the send failed; CDP_UNREACHABLE requires Desktop recovery. Remote ids must be handled on their hostId.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_new.tsx#inputJsonSchema","description":"Start a new Codex thread on this machine in cwd, optionally sending its first message. Codex must run locally on the same machine as gbot.","id":"tool:grok-bot/codex_new","inputSchema":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"type":"string"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_new.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} +{"application":{"description":"Message Grok Bot from Codex, Claude Code, and Cursor. Codex/Claude tools use local sockets on the user's registered machines only (no remote transport); from the Grok Bot box, run gbot via Grok Bot Shell with a machineId.","id":"plugin:gbot","name":"gbot","version":"0.10.2"},"compiler":{"adapters":[{"adapterRevision":"1.28.0","host":"claude","observedVersion":"2.1.260","schemas":[{"name":"hooks","revision":"2.1.260","sha256":"0cdfc5eb5201f2c3091768559ac82f4c563ccb1b7bce7a39d5f99e5f404654cb"},{"name":"lsp","revision":"2.1.260","sha256":"b4419c5d857267c7e2b21e3e1eb98b4fdc302c87109007190d3258e6ba7096e4"},{"name":"marketplace","revision":"2.1.260","sha256":"31ee4cc43ba5ce2be248030a69da2d31171550b2cc51c1fcb9f788a8ab92783d"},{"name":"mcp","revision":"2.1.260","sha256":"edd4770e41d6aee5beae1ff918d33139613a243e454ecbd52b72fa824be4a662"},{"name":"monitors","revision":"2.1.260","sha256":"6378d94b51fb7c784eaee178237008a03da0f889d0520d57486784954a1d484c"},{"name":"plugin","revision":"2.1.260","sha256":"2a976091b81ad07ae8eca57f6f9c5749efeba17fa089a0c12b6ca84d6e70f118"},{"name":"settings","revision":"2.1.260","sha256":"2bbca553621dbf9433a9b7d1ff7952543a368434f2d999a4e4e360b95b6d4c3d"},{"name":"theme","revision":"2.1.260","sha256":"9931264e6f5a1d4b3b854ce7a17d602c9ba1b57cc1991f1d3991b316eaa81ac2"}]},{"adapterRevision":"1.13.0","host":"codex","observedVersion":"0.147.0","schemas":[{"name":"app","revision":"0.147.0","sha256":"01c720a645e437bf0c4f8c26fd4cb5a13988e5649e4a8562ee23a1d4b7355c6a"},{"name":"hooks","revision":"0.147.0","sha256":"175b859eb8e85bd287d85ee840d97c3f5c2d0dda3223507a796d158e3770eeba"},{"name":"marketplace","revision":"0.147.0","sha256":"fbccce3ade39e1b077fcb440e60260de6e811e8c2d222b2ae0fe8fe47706b470"},{"name":"mcp","revision":"0.147.0","sha256":"75bd50f9fcb85c2e8d43bc132d61c172a02f28ea8bb77389816ae77b14a4257e"},{"name":"plugin","revision":"0.147.0","sha256":"074c6c71966a3e6560ccbceb8d82ec6a40cb1eccee2f2d863fb4ef1e2276a814"}]},{"adapterRevision":"1.13.0","host":"cursor","observedVersion":"2026-08-28","schemas":[{"name":"hooks","revision":"2026-08-28","sha256":"06154b7afa0861df462130b988912b897e7ccf962b8dd20c09193100bcde5d81"},{"name":"marketplace","revision":"2026-08-28","sha256":"1aae96a24c2796419933bc8bfe3a1255394e7199c35740b36325e0ce6dbc253d"},{"name":"mcp","revision":"2026-08-28","sha256":"f3fa4615afefe004c4fbcc09e635d890df0f1ec0cb39540feab72cbd3a31d844"},{"name":"plugin","revision":"2026-08-28","sha256":"a393b758901803fcf5cfe0d77bda8a83e987d32c3377dfce2d9edf445af884ed"}]},{"adapterRevision":"1.10.0","host":"portable","observedVersion":"1.0.0","schemas":[{"name":"mcp","revision":"1.0.0","sha256":"6539175bfcdf43085855183e86da40ea94b166547a72b47ae9a0a390516d3acb"},{"name":"plugin","revision":"1.0.0","sha256":"0a4aad95ce337878ad38802ebf0daa3fde76abe3f65400c86bcbb1ec0b3ab883"}]}],"agentSkills":{"schemaSha256":"6d06b61e423317421de2295ea1fd0c7b4491bfa36c5b7705c28616dfe76d4047","sourceRevision":"69ef37e9424c0a7ea9dd2293b559e43ec8176379","specification":"https://raw.githubusercontent.com/agentskills/agentskills/69ef37e9424c0a7ea9dd2293b559e43ec8176379/docs/specification.mdx"},"producer":{"name":"agent-bundle","version":"0.3.1"},"project":{"configDigest":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f","configPath":"agent-bundle.config.ts","modelDigest":"b462f5594e8174bb3c565276aa2dcb5f56094d68add7f8b991b09701ed1417a6","packageName":"grok-bot-cli","packageVersion":"0.10.2","revision":"ee63b1fe252603936f09265b7ea1f2d4a0d4092ffc862bc6ac68d393375afa06","sourceInputs":[{"executable":false,"path":".changeset/chatgpt-desktop-cdp.md","sha256":"7b79eb902697f8d0e805a98466e3d57c7a2f588b0daefbd3b83559f66e325ad9"},{"executable":false,"path":".changeset/config.json","sha256":"0a97ce5d0488bada887ee9ea3726edecc727454b7da0294f1b5fe4947f48ee7c"},{"executable":false,"path":".changeset/desktop-e2e-reliability.md","sha256":"ebb912d56ba3321df13a9d611780129af8f4c264dbc5e841df6c1a8a838dfc10"},{"executable":false,"path":".changeset/desktop-merged-pagination-projects.md","sha256":"686b95a887f227380fce54a4a36c227b8a53b924038ddaad82d1c2a778699168"},{"executable":false,"path":".changeset/README.md","sha256":"495bd4805f8362853bce99689c1cd75db8c475dfa38930619d2e197d7554db27"},{"executable":false,"path":".github/workflows/changeset.yml","sha256":"0139beb8a3dc0e95126c9701d09251a879331b1e8c5540bbfc69848525b40f23"},{"executable":false,"path":".github/workflows/ci.yml","sha256":"17a58cf5ceff03b7922d15c9b0eea11ae3e0fd00a581ff6881f69cf795f3ec0b"},{"executable":false,"path":".github/workflows/release.yml","sha256":"9c97360a2221fca9317edcac0eb343298c765e3b34bd048f916c47533dd90311"},{"executable":false,"path":".gitignore","sha256":"30aaeac24084f0a642d811aa493fc51b0fd3eddff322d359c39c573d8394ff3e"},{"executable":false,"path":".npmrc","sha256":"da47110e4c2d7cd216cd495b604ca78bd0f5caaca32da4837ec0efa6f967bba0"},{"executable":false,"path":"agent-bundle.config.ts","sha256":"7718be28a54eb7ec9e28b9653ef671683604436af21e1eda99c11098f43e278f"},{"executable":false,"path":"AGENTS.md","sha256":"e18ce90a031c533e7226789b97f6bce4aa7994b672544e0f425d20cc3bc15d29"},{"executable":false,"path":"CHANGELOG.md","sha256":"49d0b5b880153fa7be882f31c8edf73cf04fe0a5f83e2bb880a48ccda495044d"},{"executable":false,"path":"demo/grok-bot-cli-demo.gif","sha256":"0fe01e15fd2abbbc5cc3313e42931d404d3a320764e22fdcfb995f1a45dd73cd"},{"executable":false,"path":"demo/grok-bot-cli-demo.mp4","sha256":"b6ed66e43616674096c2f0a4a4da46fe4693c681833eab013f872a66b9ff933c"},{"executable":false,"path":"docs/chatgpt-desktop-cdp.md","sha256":"6dd6cfe00e9a888c1ced79f1db85744f9c92affef8a78126e22ea5205e76b732"},{"executable":false,"path":"docs/codex-busy-threads.md","sha256":"42509e8e4c2b519949f06d4e7028b8973d56f8fc0cd98decdb231375bb49d38d"},{"executable":false,"path":"docs/codex-duplex-architecture.md","sha256":"792f1be8bad508b042c5813c1fc3b7ea5ac87032803227830666727306e55fa2"},{"executable":false,"path":"docs/verification/2026-09-15-duplex.md","sha256":"c7d97f709a3c2d851c0a24690321bbda161ec925b4143a456b9951e174bf75df"},{"executable":false,"path":"LICENSE","sha256":"bc48c8a0f6b6e45842e574c79a6b955fe683ed13f48a50cc08bcccdb1a59fe59"},{"executable":false,"path":"package-lock.json","sha256":"fc92e6f62433580416ad0af5f6b7f83d422f111e5e0c2535f7934c54f9066953"},{"executable":false,"path":"package.json","sha256":"4894d2ae20d895b1b213c0bd7eb7a6c483a7ae632e49ffeaa4eb7564bc71abde"},{"executable":false,"path":"README.md","sha256":"efe1a601a87648defca4b223f5b6828ead8f17fc15ad1fb8eeac23b9b61b8b29"},{"executable":false,"path":"renovate.json","sha256":"e80b4e42a3043bc12fa0640db4bac392d2bf770acf841360d7c8ceeeac2ec1a9"},{"executable":false,"path":"rstest.route-unit.config.ts","sha256":"7286e20dc3d4162673e7c3dfe824db00307e1fda178410f23044a97286d141f2"},{"executable":false,"path":"scripts/run-unit-tests.mjs","sha256":"483f91b4856ce294a483dd2e62ca53bf09301adbc4c5fc9571da0e1d28049bc6"},{"executable":false,"path":"src/cli/_shared.ts","sha256":"555210759d9b2e2e60a01452c137abd73bad42bfab8b2311b66a3ab97f4ee5e9"},{"executable":false,"path":"src/cli/approvals/list.tsx","sha256":"8d21320b6cd9d6b2a266fd30196b8a439960f865a6f0a5dacf5845d64ed7388c"},{"executable":false,"path":"src/cli/approvals/respond.tsx","sha256":"7d9fe6e641deb08f444684733daac6da47fb472d90ed0e9ff77892f376a87255"},{"executable":false,"path":"src/cli/bots/create.tsx","sha256":"9f7a73a0595b642dd77f008ad596bcafd00fc5846ec1abff2ce62819d983eb84"},{"executable":false,"path":"src/cli/bots/delete.tsx","sha256":"126b53ac1da4a657f22d1a6770ddbab2cc66715c811de0873d50016bbe39cbf2"},{"executable":false,"path":"src/cli/bots/get.tsx","sha256":"f0c752a3b498819083a8ee5aa918d275727f1cc94d8774d8c84ac74db66e8a71"},{"executable":false,"path":"src/cli/bots/list.tsx","sha256":"21c0f7e39005860dfc2514b71f745bb4cab29d409ef2cff26f8759bb0fd261c1"},{"executable":false,"path":"src/cli/bots/update.tsx","sha256":"33b7f5aafbf931cf3cb5ecf423a76dacd09adb117a7d5490050639ae7f4210dd"},{"executable":false,"path":"src/cli/chatgpt-desktop/hosts.tsx","sha256":"64e3e873115a4f5c2b6a7fd68236dbf2ca4e4a880ba97bdd7409b48931bca632"},{"executable":false,"path":"src/cli/chatgpt-desktop/read.tsx","sha256":"11c86f604c2ee405f7544394db60ee1b36917d0b90769d441fcd361b5f0fe038"},{"executable":false,"path":"src/cli/chatgpt-desktop/search.tsx","sha256":"0dc3acdea178ff14d6c1c4b8b3bf1e18af47984f63b8ed8c41483e4da4b72f08"},{"executable":false,"path":"src/cli/chatgpt-desktop/send.tsx","sha256":"b801a028980e60fe37dca56e86887a1e2b0b8ce80ce77b379e7375d2e4544d5e"},{"executable":false,"path":"src/cli/chatgpt-desktop/status.tsx","sha256":"141b7b6db6d6f9236dd5343ca9495200752937b05764ad7fa7261631c2db5bbc"},{"executable":false,"path":"src/cli/chatgpt-desktop/threads.tsx","sha256":"d0a33935d992af349c52ef448622da5e460b4af1a9474aac60994295245b43ad"},{"executable":false,"path":"src/cli/claude/send.tsx","sha256":"d650caadec248aa59530d124ca6186c45d9f9fe1fb0f9c805e9eef6dc9f06d92"},{"executable":false,"path":"src/cli/codex/bridge/respond.tsx","sha256":"9d3a6af4904af6e44583dfb4ef317b3fe1045a78e765fc27406eaca9bcadcd13"},{"executable":false,"path":"src/cli/codex/bridge/run.tsx","sha256":"a49d334bebb00db62ad2c54370a47ec2c9119b4c07eb6ba11fc4bba4dd8e4217"},{"executable":false,"path":"src/cli/codex/bridge/start.tsx","sha256":"9e423cf5d65168606f6235baa2bcd127eb949647f7a4dee284d75f831474524d"},{"executable":false,"path":"src/cli/codex/bridge/status.tsx","sha256":"c801f69080985c87025429fb136487acdfac093acb07241b3417ea9a83915a18"},{"executable":false,"path":"src/cli/codex/bridge/stop.tsx","sha256":"6710e298a21d124c442d5aa1a3744280e5cd4df93213797f2ea3c0654174184a"},{"executable":false,"path":"src/cli/codex/desktop-shim.tsx","sha256":"fa3d88d11895bc4a15700bd590c055aa392b2b0e0c1185c52da233a23589aba0"},{"executable":false,"path":"src/cli/codex/list-threads.tsx","sha256":"6d754db238457ec63af76c0b34af47f9dc3888b2bae7cebaa7ed01135c7946e0"},{"executable":false,"path":"src/cli/codex/new.tsx","sha256":"11d0658c1a3e7173d53b71446b184fccccd867baefc6f733e43a9d543ca26ec9"},{"executable":false,"path":"src/cli/codex/queue.tsx","sha256":"7993ac5b827042cd95041775b183fde2d112b5ba7d5c82098e778a44e473826d"},{"executable":false,"path":"src/cli/codex/send.tsx","sha256":"a1b30f053a9e65bac561cd04d1361e292e2c672bbf69a6d76d2bdda441c46757"},{"executable":false,"path":"src/cli/codex/status.tsx","sha256":"b8c31001cb2892c1bfccf502f9776ee06998eac4fc0356f92936fa2c34f272d8"},{"executable":false,"path":"src/cli/codex/wait.tsx","sha256":"0a4cc6c440ad496682031658bda375fee29f5c346d833618d4f143de29b351cd"},{"executable":false,"path":"src/cli/codex/watch.tsx","sha256":"3280f42d15941cfd00b3727d9e271972c39165bd28db8f56acca5664d777cb4d"},{"executable":false,"path":"src/cli/doctor.tsx","sha256":"c30ce4e57fe707d36de29700abf5a2c56834bb4fb3adf2a70bb1089b4150ddc8"},{"executable":false,"path":"src/cli/groups/add.tsx","sha256":"2a5de115852f0ca6a6638300bd5006862a02a2f1e2f527b6fd680f610c1d777a"},{"executable":false,"path":"src/cli/groups/create.tsx","sha256":"da3f2539f338063daf51b80d86c27b2752f0e4a0334078d11508e27981590fa3"},{"executable":false,"path":"src/cli/groups/delete.tsx","sha256":"2d4e91113a2c24cefefcfd464513918791592b5e8734a4ef901eabe42c9c7289"},{"executable":false,"path":"src/cli/groups/get.tsx","sha256":"efed88fb3ab7292d60d6532f1f966f784ba3376b7826c9f3e5028467f86241e9"},{"executable":false,"path":"src/cli/groups/list.tsx","sha256":"f3cd229d41dd389b767447a04267700ab2293eae87a878f7d88149cb5798f4a6"},{"executable":false,"path":"src/cli/groups/members.tsx","sha256":"9b9eaecb65ea995006eff1b24a287110d16bf4830a0b0d07221c2f1317853641"},{"executable":false,"path":"src/cli/groups/remove.tsx","sha256":"96dd85d1b9732681ce9dc126ac3ae562d3f287f4c28e36b9a8f8c301dc93f63d"},{"executable":false,"path":"src/cli/groups/set.tsx","sha256":"4f9d90db612f14ddbb6d2afa5e45b66f044aed661ff95415e567e1be3b6108c6"},{"executable":false,"path":"src/cli/groups/update.tsx","sha256":"f44305815ddb6e27286f97ef68c04cfa5548acd5f04b1aba10ee7ce3cdbfc851"},{"executable":false,"path":"src/cli/history.tsx","sha256":"5151b48113b4ba0516bacabfabcd48e3256ead807c34d914deb84f31ded0b062"},{"executable":false,"path":"src/cli/send.tsx","sha256":"fd16790cfcde1c15328c3979acc0664112d5cf40d3f00a24da906e00dd63153e"},{"executable":false,"path":"src/cli/skills/add.tsx","sha256":"fbde237d172c026d7912174e705c03cbc9d74dad7806fc58c6ceb43127c69ba6"},{"executable":false,"path":"src/cli/skills/list.tsx","sha256":"34f255687c69aaf598a1dc54220453b57c46ed9ab4a168648d9c7eca6535ebae"},{"executable":false,"path":"src/cli/skills/remove.tsx","sha256":"21662c80a62f276c2dfd840a328e9665c0c5f63959a239d4dd877372c46f60d0"},{"executable":false,"path":"src/cli/thread.tsx","sha256":"29ab775936fa2987cb789754a44888fc52bdaad07180c5471122dda508cfd0c2"},{"executable":false,"path":"src/commands/codex-send.md","sha256":"ef29096075a13a28be9c2ee7a6226f169ffd330a7f21698b3927273070a6086d"},{"executable":false,"path":"src/commands/codex-threads.md","sha256":"bacac58bb4e61766ea76f9abad71c25207192bc609ce3bf3f122686c00d674a4"},{"executable":false,"path":"src/commands/codex-wait.md","sha256":"ef224414fe7a9f2aaaae2fba8b83f0600cb3589dfc20920a69b29db3a5f2d880"},{"executable":false,"path":"src/core/app-session.js","sha256":"2b2eb53ec3f4c7ea0dccf269fa9720af6f1ce36b8ca36e889d2bb271a092717d"},{"executable":false,"path":"src/core/chatgpt-desktop/adapter.ts","sha256":"5a0a4f2cea9f1fc1a739c534aed3979c28e0bd9c057b8475e6251974ad44ed7a"},{"executable":false,"path":"src/core/chatgpt-desktop/app-server-fallback.ts","sha256":"44002096eea29b5ea26d5b3d186b5616fcdab570888e3cb86fd4b5c5804af04c"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-adapter.ts","sha256":"db60fdd3be0259a6c76cad7d8ff86eddc6acbbd21c5f20d6aeffff5390063efa"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-dom.ts","sha256":"a122fb76626006fa8dedb7088f9b5533a8058c3a58838692b168e0753b7c89eb"},{"executable":false,"path":"src/core/chatgpt-desktop/cdp-session.ts","sha256":"8d6512ee80b179eedf54504110c1e88c5233b0b922667b00f87751452164cc00"},{"executable":false,"path":"src/core/chatgpt-desktop/errors.ts","sha256":"941ce4a9148fc53086cce64336dba473c1f7e4138774fd50a8ae524dcc05d34d"},{"executable":false,"path":"src/core/chatgpt-desktop/facade.ts","sha256":"bc9ac3bfd24db8458af6d20893fb3ab2ed701778f709aadbd141d61ed6c6c29b"},{"executable":false,"path":"src/core/chatgpt-desktop/index.ts","sha256":"591e6968c008cc75827da94b91c0ea15e573640876814e35e2470342dc8bccf9"},{"executable":false,"path":"src/core/chatgpt-desktop/loopback.ts","sha256":"b746681e5c45c67445e6620f850eff7c4627e13979747a7f686374c10a51f52f"},{"executable":false,"path":"src/core/chatgpt-desktop/payload-budget.ts","sha256":"89410474315b3769bad58d3ab61999e169410b7d1fdc20819efb4ee9c82fe1ac"},{"executable":false,"path":"src/core/chatgpt-desktop/project-state.ts","sha256":"b33e55b6d6abf15f3d7d1489b8b178d4e907ea83ed1a47d88f8f178a574709f8"},{"executable":false,"path":"src/core/chatgpt-desktop/relaunch.ts","sha256":"14851e115de7c45e256c4b9c3829dc4e796f1d989cf67d65115701a30b6d3a81"},{"executable":false,"path":"src/core/chatgpt-desktop/remote-threads.ts","sha256":"ed93418ff5d2bb51016783e7b0a458805e709b212974a66be804ddb9f7038033"},{"executable":false,"path":"src/core/chatgpt-desktop/routes.ts","sha256":"ccf8cde780da6e6e03f11e4dcc0d9d6bc4a6a3fd20d3210e74f0217e3660b7e1"},{"executable":false,"path":"src/core/chatgpt-desktop/thread-ids.ts","sha256":"0fe25e9d32c078bd9e7a171ab4bc4ee0b15190cd6d6c4d3b345926b3c608e082"},{"executable":false,"path":"src/core/chatgpt-desktop/types.ts","sha256":"59f89694eed34206e32db2a0afb48670bb164a4ffffacb907c8629bb0ce4bcca"},{"executable":false,"path":"src/core/claude-channel.js","sha256":"01ac7daef748a11bc99e132950ed7c59f50442e417eecf894b59cb4bb484202f"},{"executable":false,"path":"src/core/claude-routes.ts","sha256":"d34ddf25b8634ef86d46ab663f30a49aaedf87f8dc98e4036f84c1c88efa4083"},{"executable":false,"path":"src/core/codex-bridge.js","sha256":"78f0fbba7a5053eb78717c5885a9306871f08beaf39da90df1f815a66b1288d9"},{"executable":false,"path":"src/core/codex/contract.js","sha256":"16bcbd0fc09844166c52694ebb1075e60b91296a8f04fb02ad061c30b0e9c591"},{"executable":false,"path":"src/core/codex/conversation.js","sha256":"05abb2253480d0793bf5f6b3db17c47e7d154973747074c7c76a79e6f61b7deb"},{"executable":false,"path":"src/core/codex/remote-control.js","sha256":"52565007799e98c3bff4297287d8e53005e285a95bab9e4e4d0a088bded4fa8e"},{"executable":false,"path":"src/core/codex/routes.ts","sha256":"ae29d05e06cdd8e90bcdd723d277af748e16dc676db1e4b938b7cdd36340ed17"},{"executable":false,"path":"src/core/codex/thread-id.js","sha256":"4eb6c1929c2e7687ed6c1422789fa01c3e1c556ead7d16355eafbae46a7126f4"},{"executable":false,"path":"src/core/commands.js","sha256":"3ad8fafb86744a57992da93ad838ade0e9acb1b7ca09b829cefadbf2781be0c9"},{"executable":false,"path":"src/core/desktop-shim-bridge.js","sha256":"58f3f39b8527adf58f57313e02e34322b203b8c38d1acfbad419a8b9af214443"},{"executable":false,"path":"src/core/desktop-shim.js","sha256":"500b8617bade6fa1a9c395826e197892fb864067044cac80ab025849f8fd6f82"},{"executable":false,"path":"src/core/format.js","sha256":"83ee15f73a87ef24b75f7782f3b61dd4ef4cc1f2e01e38cdf19825b805fab3be"},{"executable":false,"path":"src/core/gateway.js","sha256":"3a4f838ee423600d29e05f58060dcaf81cdcea4ac93b36dd6108363ac24bc606"},{"executable":false,"path":"src/core/grok-approval-routes.ts","sha256":"a33daa4d05e0c2594c795bd7654c22f3e1003e4aaad41cd70034d03651dd01f9"},{"executable":false,"path":"src/core/grok-approvals.js","sha256":"6b651a65bdd17241dd5b7a01d94a318ece9356c1c9b965b0578e08250d74e8fe"},{"executable":false,"path":"src/core/headers.js","sha256":"e229f2826ebdfb52949dab500798c0fa8a5ff7c4e63de91a63103bf45d2ae3cc"},{"executable":false,"path":"src/core/history.js","sha256":"38ca8e8f8dcd2ad42952c424ea9f00be5972d8751e4c0ac87214171903d82d89"},{"executable":false,"path":"src/core/relay/codex.js","sha256":"ff6e8f3158d171911a35b829cd76e1f5fd8319f8143f727a4854448fc09edeec"},{"executable":false,"path":"src/core/relay/completion.js","sha256":"9d1a47f92716d1ccc7c4f44d92a580084f3b622c6ac0f20c6391be81abeb56e4"},{"executable":false,"path":"src/core/relay/control.js","sha256":"3645540f9f799b8742e0d5782b6324454a1486a780f6cb97260b96ef62411771"},{"executable":false,"path":"src/core/relay/engine.js","sha256":"205dd43b337439a56c7b1521b2603679ebc7fd3b2da430f8a477f83549efd453"},{"executable":false,"path":"src/core/relay/intake.js","sha256":"b31146fe3c9edd2f09323a454687403666591b6c12483a55b07ac610d2e3610a"},{"executable":false,"path":"src/core/relay/interactions.js","sha256":"6b576ed3a5b6659bc17e384d26e40d6ccb41b118b3a91cf5c902e9758ccbc1b1"},{"executable":false,"path":"src/core/relay/managed.js","sha256":"dbe03ed964bd09739e580de73b7e9f90508062fa2e53b8244c6ca7f78fc7a60d"},{"executable":false,"path":"src/core/relay/ownership.js","sha256":"74805f04f6a8bc02b2951614c4814aa42f54aaa3abca027a2413ed5a54814caf"},{"executable":false,"path":"src/core/relay/profile.js","sha256":"3347d1d493d3470d82722468d31571464d8e11aa0b4deac5bda75f574078dfe5"},{"executable":false,"path":"src/core/relay/records.js","sha256":"5b80f7dfe7e438811d9f27c1f9038d7631f8c73266d2ec7b1108c1ce9ecbbb47"},{"executable":false,"path":"src/core/relay/routes.ts","sha256":"4007e9908e285036786b7b0291dd480d03d51ad03f973fa578444accffa1f416"},{"executable":false,"path":"src/core/relay/state.js","sha256":"c18eda2f956944d0f318910de5239b954090eab81f7c77b4683e326a6d34b2b8"},{"executable":false,"path":"src/core/relay/worker.js","sha256":"4176ad91872f36f7ea6565d9f30d23d9d7a80ef27d7af975af760457132ba148"},{"executable":false,"path":"src/core/store.js","sha256":"caefeeebf686cecd37ef19585ef0a5d3acba9dbf1564fe128c3afe4de067305c"},{"executable":false,"path":"src/core/transcript.js","sha256":"0355f0978d2d126b90858e3f661130243fc4730ee81ba13080af1dfa39d8b081"},{"executable":false,"path":"src/core/url-policy.js","sha256":"62bf6d3c8af1f5840d5e2d682d8f2e52fcbfbee6695728b47ed31816f1736089"},{"executable":false,"path":"src/core/user-machine-guidance.js","sha256":"c8409ae9679246d8f907f1e0d16ec1c415d6697f2ce048fb64a599734486b9a6"},{"executable":false,"path":"src/gbot-install.ts","sha256":"e3c833d7662610e70e65232e541017229fb9a049eacee0bdf31e2c33c6ab7189"},{"executable":false,"path":"src/gbot.ts","sha256":"c89a37b764956ceacb2917a991a6d82d987ed8d8e453c8d553485bbd7f3edcc0"},{"executable":false,"path":"src/mcp/claude-channel.ts","sha256":"2d52e0d862a492026b6cb408e3177c994996e2b4292903da5bbf5bc191019913"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","sha256":"86334421686350ea044fb1160c19b6f5889425feb78fd608675feb8137492090"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","sha256":"5f24cfdace92522891dfbaed0bd90e74b7de6bb8d193e0ef3bd5582c05a06914"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","sha256":"b415d5bd303693649abae96b6b9d2920d29c797f5367ae8fbb2b62b635528e37"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","sha256":"6adc4318f4b6c90b1d3970046266197348f79757c0d52ffe991d6338eb1fed6c"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","sha256":"1d50db88cf7d06a74524c8937ed9045eaaf2560f6766d6c411b3bb55575d1d3f"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","sha256":"9e1b93735b9a38216c7e9aac4c5b62bc2ac20b60e1979a19c4610f0208961af5"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","sha256":"681e50ae6c7d3a04a76ad8eadf865ab9d793b5eb3c78f961a42d0902adacc306"},{"executable":false,"path":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","sha256":"2786b62ff2a1a4e68229199935ac63c15614a0f0bdbef74b2d06e0c405516272"},{"executable":false,"path":"src/mcp/grok-bot/tools/claude_send.tsx","sha256":"c02924049f370d9cb5ae459d6275c6cae2c9f4f1328cb5fa8e2f3e6d12a6d656"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_new.tsx","sha256":"556c8d6f5f2b07b20e9daae7aa8008ee3775582a4d034415fc86fecda0c63866"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_send.tsx","sha256":"5c02dc335a0354850d05e5827f6124d0ddc08b9b654059984887c55e4cd778c9"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_threads.tsx","sha256":"0164fc0c7b49df6524d56380763349cdd5ca26c68cffa5979b4e3346593ba2e4"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_wait.tsx","sha256":"cb08b094860f3a09c937eb8339108015fe0de57d9f6c6886aea2028cd33ef207"},{"executable":false,"path":"src/mcp/grok-bot/tools/codex_watch.tsx","sha256":"1bc603d36ea7542468e7e3eadbb86072990282e09e209f13ebfc64389d207c49"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx","sha256":"c75c5c8a30ec43709a4d32baa8c3bc9796595381bb04fd2499ca30cd515c5a0b"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx","sha256":"486ce643b35cfa2eabf78f0deeabce7198adc66133669eec630e1d12206ad642"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","sha256":"371428a6e4b4e1312dd95d9681c29e765aec55e65d80d7c474535df838a43457"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx","sha256":"030e9c2081ed4ed40732b098c929022af3083f609f10934b35e1f428d33ae637"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","sha256":"17f164acdc48d6bc79a4c5044c7082760dd2a1646e5b56f6bff54c53fed96451"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx","sha256":"41964bb8cf0eb0f8493afa1dde16cd94c4f589d1a7e410577d1ed63ec4648542"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_send.tsx","sha256":"2101d279a0e6bda2d57ba3da5366411df460a95692d4e64a1096880a89121d9a"},{"executable":false,"path":"src/mcp/grok-bot/tools/gbot_thread.tsx","sha256":"ef4aefec7243efaad18335e8508c7c17af0cd9b0f8a4b3693a7af9f666807fd6"},{"executable":false,"path":"src/rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"executable":false,"path":"src/scripts/gbot-relay.ts","sha256":"6690e316189ed8ebba43ea67a495338c927e4c0c21a9f896b7b2fecc8c6eb656"},{"executable":false,"path":"src/skills/chatgpt-desktop/SKILL.md","sha256":"0fe2560037f761203a317bf8755b0476ce864b7b1b13708559448d300aa4635c"},{"executable":false,"path":"src/skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"executable":false,"path":"src/skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"},{"executable":false,"path":"test/app-session.test.js","sha256":"0756b691703dd8c84bf0823f2afab16c6b158398e4ce6be229db6f459a0bbdb1"},{"executable":false,"path":"test/claude-channel.test.js","sha256":"c63337698001b9739414203d70b6d54d0794ec5970bd90d327923f50ab2355dc"},{"executable":false,"path":"test/codex-bridge.test.js","sha256":"55a1afcdea07f325b3528dd0c546ecc4cbfd6069610ecc4f773f049cd597e69c"},{"executable":false,"path":"test/codex-commands.test.js","sha256":"ab15a53a76eb82dc9c51c9fabd0affd2a1037cde27765fef08ecd0012a2e4495"},{"executable":false,"path":"test/codex-contract.test.js","sha256":"926c7609679d8b6ac3b568d56ba5efa20df86d016a9031f085d19adbfb0e9064"},{"executable":false,"path":"test/codex-conversation.test.js","sha256":"789d0245a8d470860f7535c6ef3849313205097f6df517ab9946e47a789f8534"},{"executable":false,"path":"test/codex-session.test.js","sha256":"b39fe6afe0784b16e37b208089279dea01095d33e06ae26a1b60871796c7738a"},{"executable":false,"path":"test/codex-surfaces.test.js","sha256":"56d1b6550cc69d462a05e892cf82aa6a41495857b753215104e03207db514c81"},{"executable":false,"path":"test/connect-gateway.test.js","sha256":"5fabd87640b39e75c218300ca6be278268f248f3ff75e8cb72f9fade9eb0f7f3"},{"executable":false,"path":"test/desktop-shim.test.js","sha256":"89fb6c38a5fca5d41a96434cf9e8d51ae1d9992cf4f7930df0cc5840ef985705"},{"executable":false,"path":"test/doctor.test.js","sha256":"9685885df9e7363d3e077d246b1a17803c8899e9613b4a4d52ee4b9275e20694"},{"executable":false,"path":"test/gateway-groups.test.js","sha256":"14e227453e3e28c7cb60f91dba55733834c023ce9a914e40e22c68c899512bdc"},{"executable":false,"path":"test/gateway-send.test.js","sha256":"d059166153dde975f457e4e8c32ea08b0fc857b58fd48eab7da1959638e4fb05"},{"executable":false,"path":"test/gateway-skills.test.js","sha256":"feed62a884d1b7d12e358a27d73fb5587bcf761d4867ab1755d8bc34a4380069"},{"executable":false,"path":"test/gateway.test.js","sha256":"e5a7acd7ae347c82ef1e2a6000562767168e56d6f9d86aca8da46141731d1309"},{"executable":false,"path":"test/grok-approvals.test.js","sha256":"5ad4c548060a08dbe57949ab5ae240383fdb1709cd3694a909f5e1354fee3f73"},{"executable":false,"path":"test/helpers/codex-server.js","sha256":"432b4570601e94cf08c4861133d328404a97066642edb7ec0dbc314411a4d848"},{"executable":false,"path":"test/history.test.js","sha256":"eac4811f1b12d427df66996f33dd46bc3cbe31fc9fa030b3f32c571d5379f8dd"},{"executable":false,"path":"test/host-tool-inventory.test.js","sha256":"fa44f15f46d0cae486c13be3fae09568f17f8581001ec50a61478bec03f4c28c"},{"executable":false,"path":"test/pr69-integration.test.js","sha256":"a5dc99c11e2d3fcf18233c595f9c28301e5939f4b3657125eb3f970df2598840"},{"executable":false,"path":"test/relay-auth-recovery.test.js","sha256":"399c064f550fe33e166187a51da527728a97946d213377c8fcc8231378f5bbab"},{"executable":false,"path":"test/relay-codex.test.js","sha256":"43cb313e748e187f798a8a0bce5a01cce9ba360a52985b05ecededee9ad10581"},{"executable":false,"path":"test/relay-completion.test.js","sha256":"a8cc2402f82ce4b458074eafd32c8fa18f7ced7d85fdb6b7fa68f7b18b6a8c2e"},{"executable":false,"path":"test/relay-engine.test.js","sha256":"a8c06138d895ffaa30476f3a2ddf1ef50ef73a816a665f749f451d01d9cc2551"},{"executable":false,"path":"test/relay-gateway-lifecycle.test.js","sha256":"e16e7a34f7b6bb07965003e3018aa3a43ff192602db1c177bec9b6268fddb78b"},{"executable":false,"path":"test/relay-interactions.test.js","sha256":"83d70b1a813923fc6bae02b18d328107d0d04a6a761ab73b2051e3d114c7eaa5"},{"executable":false,"path":"test/relay-lifecycle.test.js","sha256":"e90130e1f609839bfd3f74c3edc333a22f37fe20dcde0146daa8d497133da4b7"},{"executable":false,"path":"test/relay-state.test.js","sha256":"c9143d5fa150b1ebcef9d515e161e25af3370b71eaf800a7b2bb1da1678b0bd3"},{"executable":false,"path":"test/relay-surfaces.test.js","sha256":"ba17ac4f1ffc02d4e06cd73eda143422a3d4d2f750630af9ed4e828dc9d7d2be"},{"executable":false,"path":"test/relay-worker.test.js","sha256":"6bd1bdaaaae59997132f289f822b6c4b8c9616c268fb2b45861e03f697c08197"},{"executable":false,"path":"test/release-config.test.js","sha256":"f3078277086d722f21d07e4134e10b89d2e849a94a0fa40f30025a5cb6fa6a15"},{"executable":false,"path":"test/store.test.js","sha256":"5d4ae4295287539ef4b7f98d0ca0cd42a931a3c7b25b092fbd2b8f1a08ca4bac"},{"executable":false,"path":"test/test-runner.test.js","sha256":"966ff3b67edb8e1f03b50120d4d820ab0f871121e9b359609e73faae8446454f"},{"executable":false,"path":"test/transcript.test.js","sha256":"28795d9cc8e42653ac430d18e17ff1e6bc2feb1b7935fe5c69b336d58e1793ae"},{"executable":false,"path":"test/url-policy.test.js","sha256":"dacfe322e0cbff178c0d67a5f76b6bd8d9fef14aa57c09c697eb69fa0019629c"},{"executable":false,"path":"tests/fixtures/codex-global-state-remote.json","sha256":"e59377d0f03cb24d57b55558e9c91dd363619a8a92566835f1ad49b639f99525"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts","sha256":"9cfc7f538899954970fe643c13571f03d417450c519525e91d382a0b5f0b086a"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-mcp-followup.test.ts","sha256":"4a2db11a642b8daef05285f096ce026ca5b9b6394c31c0966d7e5f8c1d49f4ca"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop-review.test.ts","sha256":"208dfdea18ccc408a279666a521d2f70fdce9bdaf28f86bc5d053f7ad09a7dd2"},{"executable":false,"path":"tests/route-unit/chatgpt-desktop.test.ts","sha256":"5cf61e174b1d4a7c0f2209d6746bb1880a96fe550f7d2c4ea94e849dd7f21299"},{"executable":false,"path":"tests/route-unit/tools.test.ts","sha256":"7c7d971edaa7ef134d0dfba12208f88ec7f69c11dca79ad61d6e6cfae6d34c43"},{"executable":false,"path":"tsconfig.json","sha256":"fa2ced6d1721e8280a6aed615717cffcef25f6e2d16e15889b2be2a9df4fc226"}]},"provenance":[{"path":".agents/plugins/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".claude-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":".claude-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".codex-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".codex-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".cursor-plugin/marketplace.json","sourceInputs":["agent-bundle.config.ts"]},{"path":".cursor-plugin/mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":".cursor-plugin/plugin.json","sourceInputs":["agent-bundle.config.ts","package.json","src/commands/codex-send.md","src/commands/codex-threads.md","src/commands/codex-wait.md","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/rules/codex-claude-on-user-machines.mdc","src/skills/chatgpt-desktop/SKILL.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":".mcp.json","sourceInputs":["agent-bundle.config.ts","src/mcp/claude-channel.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"agent-bundle.compile-evidence.json","sourceInputs":["agent-bundle.config.ts"]},{"path":"bin/gbot-flight.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/new.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/project-state.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"bin/gbot.mjs","sourceInputs":["agent-bundle.config.ts","package.json","src/cli/_shared.ts","src/cli/approvals/list.tsx","src/cli/approvals/respond.tsx","src/cli/bots/create.tsx","src/cli/bots/delete.tsx","src/cli/bots/get.tsx","src/cli/bots/list.tsx","src/cli/bots/update.tsx","src/cli/chatgpt-desktop/hosts.tsx","src/cli/chatgpt-desktop/read.tsx","src/cli/chatgpt-desktop/search.tsx","src/cli/chatgpt-desktop/send.tsx","src/cli/chatgpt-desktop/status.tsx","src/cli/chatgpt-desktop/threads.tsx","src/cli/claude/send.tsx","src/cli/codex/bridge/respond.tsx","src/cli/codex/bridge/run.tsx","src/cli/codex/bridge/start.tsx","src/cli/codex/bridge/status.tsx","src/cli/codex/bridge/stop.tsx","src/cli/codex/desktop-shim.tsx","src/cli/codex/list-threads.tsx","src/cli/codex/new.tsx","src/cli/codex/queue.tsx","src/cli/codex/send.tsx","src/cli/codex/status.tsx","src/cli/codex/wait.tsx","src/cli/codex/watch.tsx","src/cli/doctor.tsx","src/cli/groups/add.tsx","src/cli/groups/create.tsx","src/cli/groups/delete.tsx","src/cli/groups/get.tsx","src/cli/groups/list.tsx","src/cli/groups/members.tsx","src/cli/groups/remove.tsx","src/cli/groups/set.tsx","src/cli/groups/update.tsx","src/cli/history.tsx","src/cli/send.tsx","src/cli/skills/add.tsx","src/cli/skills/list.tsx","src/cli/skills/remove.tsx","src/cli/thread.tsx","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/project-state.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/commands.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/format.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/history.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts"]},{"path":"commands/codex-send.md","sourceInputs":["src/commands/codex-send.md"]},{"path":"commands/codex-threads.md","sourceInputs":["src/commands/codex-threads.md"]},{"path":"commands/codex-wait.md","sourceInputs":["src/commands/codex-wait.md"]},{"path":"INSTALL.md","sourceInputs":["agent-bundle.config.ts"]},{"path":"install.mjs","sourceInputs":["agent-bundle.config.ts"]},{"path":"mcp.json","sourceInputs":["src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"]},{"path":"mcp/mcp-claude-channel-8029413c.mjs","sourceInputs":["src/core/claude-channel.js","src/core/user-machine-guidance.js","src/mcp/claude-channel.ts"]},{"path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/project-state.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_new.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"mcp/mcp-grok-bot-b8c2461e.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/chatgpt-desktop/app-server-fallback.ts","src/core/chatgpt-desktop/cdp-adapter.ts","src/core/chatgpt-desktop/cdp-dom.ts","src/core/chatgpt-desktop/cdp-session.ts","src/core/chatgpt-desktop/errors.ts","src/core/chatgpt-desktop/facade.ts","src/core/chatgpt-desktop/loopback.ts","src/core/chatgpt-desktop/payload-budget.ts","src/core/chatgpt-desktop/project-state.ts","src/core/chatgpt-desktop/remote-threads.ts","src/core/chatgpt-desktop/routes.ts","src/core/chatgpt-desktop/thread-ids.ts","src/core/claude-channel.js","src/core/claude-routes.ts","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/routes.ts","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approval-routes.ts","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/control.js","src/core/relay/managed.js","src/core/relay/profile.js","src/core/relay/routes.ts","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/gbot.ts","src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx","src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx","src/mcp/grok-bot/tools/claude_send.tsx","src/mcp/grok-bot/tools/codex_new.tsx","src/mcp/grok-bot/tools/codex_send.tsx","src/mcp/grok-bot/tools/codex_threads.tsx","src/mcp/grok-bot/tools/codex_wait.tsx","src/mcp/grok-bot/tools/codex_watch.tsx","src/mcp/grok-bot/tools/gbot_bridge_start.tsx","src/mcp/grok-bot/tools/gbot_bridge_status.tsx","src/mcp/grok-bot/tools/gbot_bridge_stop.tsx","src/mcp/grok-bot/tools/gbot_codex_respond.tsx","src/mcp/grok-bot/tools/gbot_grok_approvals.tsx","src/mcp/grok-bot/tools/gbot_grok_respond.tsx","src/mcp/grok-bot/tools/gbot_send.tsx","src/mcp/grok-bot/tools/gbot_thread.tsx"]},{"path":"plugin.json","sourceInputs":["agent-bundle.config.ts","package.json"]},{"path":"rules/codex-claude-on-user-machines.mdc","sourceInputs":["src/rules/codex-claude-on-user-machines.mdc"]},{"path":"scripts/gbot-relay.mjs","sourceInputs":["package.json","src/core/app-session.js","src/core/codex-bridge.js","src/core/codex/contract.js","src/core/codex/conversation.js","src/core/codex/remote-control.js","src/core/codex/thread-id.js","src/core/desktop-shim-bridge.js","src/core/desktop-shim.js","src/core/gateway.js","src/core/grok-approvals.js","src/core/headers.js","src/core/relay/codex.js","src/core/relay/completion.js","src/core/relay/control.js","src/core/relay/engine.js","src/core/relay/intake.js","src/core/relay/interactions.js","src/core/relay/ownership.js","src/core/relay/profile.js","src/core/relay/records.js","src/core/relay/state.js","src/core/relay/worker.js","src/core/store.js","src/core/transcript.js","src/core/url-policy.js","src/core/user-machine-guidance.js","src/scripts/gbot-relay.ts"]},{"path":"skills/chatgpt-desktop/SKILL.md","sourceInputs":["src/skills/chatgpt-desktop/SKILL.md"]},{"path":"skills/talk-to-grok-bot/references/bridge-administration.md","sourceInputs":["src/skills/talk-to-grok-bot/references/bridge-administration.md","src/skills/talk-to-grok-bot/SKILL.md"]},{"path":"skills/talk-to-grok-bot/SKILL.md","sourceInputs":["src/skills/talk-to-grok-bot/SKILL.md"]}],"recordVersion":1,"validation":{"artifact":{"status":"passed"},"projections":[{"host":"claude","status":"passed"},{"host":"codex","status":"passed"},{"host":"cursor","status":"passed"},{"host":"portable","status":"passed"}],"source":{"status":"passed"}}},"distribution":{"channels":["local","npm"],"install":{"instructions":"INSTALL.md","script":"install.mjs"},"payloads":[]},"executables":{"bins":[{"hosts":["claude","codex","cursor","portable"],"name":"gbot","path":"bin/gbot.mjs","worker":"bin/gbot-flight.mjs"}],"hooks":[],"mcpServers":[{"apps":[],"hosts":["claude"],"id":"mcp:claude-channel","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-claude-channel-8029413c.mjs","env":{}},"name":"claude-channel","transport":"stdio"},{"apps":[],"hosts":["claude","codex","cursor","portable"],"id":"mcp:grok-bot","kind":"compiled","launch":{"args":[],"entry":"mcp/mcp-grok-bot-b8c2461e.mjs","env":{},"worker":"mcp/mcp-grok-bot-b8c2461e-flight.mjs"},"name":"grok-bot","transport":"stdio"}],"scripts":[{"hosts":["claude","codex","cursor","portable"],"id":"script:gbot-relay","mode":"bundle","name":"gbot-relay","path":"scripts/gbot-relay.mjs"}]},"files":[{"bytes":225,"kind":"generated","path":".agents/plugins/marketplace.json","sha256":"54d575719e003eb71ba2d7fb7379e12098243e701646e0ca83dba38ef2a78b1d"},{"bytes":926,"kind":"generated","path":".claude-plugin/marketplace.json","sha256":"a8f5bf1f109d8f88b4195f3baea389e942af2f0ef544ecc22502326bcf3e742e"},{"bytes":339,"kind":"generated","path":".claude-plugin/plugin.json","sha256":"1420b97dfe289c97c24e855ba758439c94fa0e92aa38aae467312fbe341d5d15"},{"bytes":156,"kind":"generated","path":".codex-plugin/mcp.json","sha256":"4b442017d0d30ec207cef7a4e5d2cd9dca246080008633459a27e3a5f2f7935b"},{"bytes":1310,"kind":"generated","path":".codex-plugin/plugin.json","sha256":"a3ab79672b9ab74affae23c25ef06ddc926da90d0ff2499e9471c3e4c6ba475f"},{"bytes":332,"kind":"generated","path":".cursor-plugin/marketplace.json","sha256":"297ba8aebcdb8bcac814b520bf21d9d6acc9c8c94a1ecf3ca442a49d834aab59"},{"bytes":169,"kind":"generated","path":".cursor-plugin/mcp.json","sha256":"95c87d0f2ed3a4f6df7d0e519454b1234672eca030db3b8cd8776ef0f35dee74"},{"bytes":694,"kind":"generated","path":".cursor-plugin/plugin.json","sha256":"12321577920803f3d60bf071167f8b7888d94d720d06c5caa38f3b30c8bfda73"},{"bytes":363,"kind":"generated","path":".mcp.json","sha256":"5c56ac183c3d4fcbfa9386a73ab805495c6ab613b96bf71dbd5be80093e1a10b"},{"bytes":22592,"kind":"generated","path":"agent-bundle.compile-evidence.json","sha256":"0a1a4dbdf3fcea9ed7e5f636963c12067c66ad28f0433b35a9b1d99385982c3b"},{"bytes":1592195,"kind":"bundle","path":"bin/gbot-flight.mjs","sha256":"b0a314b26965679b91a06be788337603c12006f3061beebb5f4a682e6e26a581"},{"bytes":2462573,"kind":"bundle","mode":493,"path":"bin/gbot.mjs","sha256":"1da1b6468f12930e44b9be5422ada37905e0ea0a558569d98d8da17df9e2362f"},{"bytes":290,"kind":"generated","path":"commands/codex-send.md","sha256":"6d188a21596115f4aa65e39718cede5eff837749c8652a12e2a5b25d8a3e0ef3"},{"bytes":195,"kind":"generated","path":"commands/codex-threads.md","sha256":"0db562fff831ede9dd300552aecc5b29d347c94ebeb3df9f488cb1a87b990cf8"},{"bytes":205,"kind":"generated","path":"commands/codex-wait.md","sha256":"fb04448a474b2f14ddb59739d5f79bcf251a3e1136ffe9b3e50ca5654aa6070b"},{"bytes":22762,"kind":"generated","path":"INSTALL.md","sha256":"5fdafbf8a3fa3d2205e6a308d37deb8ad31910927334a855f70e11977d43f6a9"},{"bytes":78560,"kind":"generated","path":"install.mjs","sha256":"d5c328ca82057cd05b90372a8cfa8ed3e8c6f7f1b14b1f579ae82250722c3d93"},{"bytes":246,"kind":"generated","path":"mcp.json","sha256":"c06a01fa851792f42e0cc807a444e454c3ea2fd164dc1c2adef455acc93879e2"},{"bytes":2270116,"kind":"bundle","path":"mcp/mcp-claude-channel-8029413c.mjs","sha256":"3a966160704621cd614ae9217051b2a681c0c913dd7507020c71c79f02161486"},{"bytes":1523717,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e-flight.mjs","sha256":"0c9ab3f71ae43f71263cae3d55b241e731ae663ecbe580c31e3a50d63e3a3a3d"},{"bytes":3351174,"kind":"bundle","path":"mcp/mcp-grok-bot-b8c2461e.mjs","sha256":"44bb2d1883bb081e78d216914a6adcb54b5d2d3ddb811f52bb486dcee63c6fd7"},{"bytes":681,"kind":"generated","path":"plugin.json","sha256":"862f9ff4c106a5b4c3bb09d498a2f395e3450074c8c79525c3a34aa67179d594"},{"bytes":953,"kind":"generated","path":"rules/codex-claude-on-user-machines.mdc","sha256":"a50ec93d021a807e0a18bf9311cdf103bc0ae3947e4c6a0bd78cbb941e8e5b24"},{"bytes":1305648,"kind":"bundle","path":"scripts/gbot-relay.mjs","sha256":"faf9fe6e3f82f9ae4a7ea61d04c2099c98057e325888e8769aa552b339c046cb"},{"bytes":4856,"kind":"copy","path":"skills/chatgpt-desktop/SKILL.md","sha256":"0fe2560037f761203a317bf8755b0476ce864b7b1b13708559448d300aa4635c"},{"bytes":6007,"kind":"copy","path":"skills/talk-to-grok-bot/references/bridge-administration.md","sha256":"3fc7d335822d9021cbd3770af6d7e95734d9213cd7331f41602598911c15ddf6"},{"bytes":4067,"kind":"copy","path":"skills/talk-to-grok-bot/SKILL.md","sha256":"b80a88ea029564447a79dbc1a533191dc4839791368c6248c904bcfaf3ccb770"}],"manifestVersion":6,"projections":[{"builtInHost":"claude","documents":{"marketplace":".claude-plugin/marketplace.json","mcp":".mcp.json","plugin":".claude-plugin/plugin.json"},"host":"claude","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"codex","documents":{"marketplace":".agents/plugins/marketplace.json","mcp":".codex-plugin/mcp.json","plugin":".codex-plugin/plugin.json"},"host":"codex","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"cursor","documents":{"marketplace":".cursor-plugin/marketplace.json","mcp":".cursor-plugin/mcp.json","plugin":".cursor-plugin/plugin.json"},"host":"cursor","marketplace":{"name":"gbot-marketplace"}},{"builtInHost":"portable","documents":{"mcp":"mcp.json","plugin":"plugin.json"},"host":"portable"}],"routes":{"cli":{"commands":[{"aliases":[],"description":"List current Grok approval cards (latest 200 entries).","exitCode":"zero","options":[{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["approvals","list"],"routeId":"cli:approvals/list"},{"aliases":[],"description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","exitCode":"zero","options":[{"choices":["accept","decline"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":true},{"key":"entryId","kind":"string","option":"entry-id","repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":true},{"key":"target","kind":"string","option":"target","repeated":false,"required":true}],"path":["approvals","respond"],"routeId":"cli:approvals/respond"},{"aliases":[],"description":"Create a Grok Bot bot.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","create"],"routeId":"cli:bots/create"},{"aliases":[],"description":"Delete a bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","delete"],"routeId":"cli:bots/delete"},{"aliases":[],"description":"Show one bot or group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["bots","get"],"routeId":"cli:bots/get"},{"aliases":[],"description":"List Grok Bot bots (not groups).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["bots","list"],"routeId":"cli:bots/list"},{"aliases":[],"description":"Update a bot or group profile.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["bots","update"],"routeId":"cli:bots/update"},{"aliases":[],"description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","exitCode":"result","options":[{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","hosts"],"routeId":"cli:chatgpt-desktop/hosts"},{"aliases":[],"description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","exitCode":"result","options":[{"description":"Opaque nextCursor from the prior read page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Recent default 100; full default 2000","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","read"],"routeId":"cli:chatgpt-desktop/read"},{"aliases":[],"description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a prior search page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max matches (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"query","kind":"string","option":"query","positional":0,"repeated":false,"required":true}],"path":["chatgpt-desktop","search"],"routeId":"cli:chatgpt-desktop/search"},{"aliases":[],"description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","exitCode":"result","options":[{"key":"openTimeoutMs","kind":"number","option":"open-timeout-ms","repeated":false,"required":false},{"key":"port","kind":"number","option":"port","repeated":false,"required":false},{"key":"project","kind":"string","option":"project","repeated":false,"required":false},{"key":"text","kind":"string","option":"text","positional":0,"repeated":true,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":false},{"description":"Explicitly unarchive an existing archived thread before sending.","key":"unarchive","kind":"boolean","option":"unarchive","repeated":false,"required":false}],"path":["chatgpt-desktop","send"],"routeId":"cli:chatgpt-desktop/send"},{"aliases":[],"description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","exitCode":"result","options":[{"description":"Local CDP port (default 9222)","key":"port","kind":"number","option":"port","repeated":false,"required":false}],"path":["chatgpt-desktop","status"],"routeId":"cli:chatgpt-desktop/status"},{"aliases":[],"description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","exitCode":"result","options":[{"description":"Opaque nextCursor from a previous page","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"choices":["host"],"description":"Group results by host (grouping mode, not a host id)","key":"groupBy","kind":"enum","option":"group-by","repeated":false,"required":false},{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","key":"host","kind":"string","option":"host","repeated":false,"required":false},{"description":"Max threads (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","key":"modelProvider","kind":"string","option":"model-provider","repeated":false,"required":false},{"description":"Local CDP port","key":"port","kind":"number","option":"port","repeated":false,"required":false},{"description":"Project label or projectId filter.","key":"project","kind":"string","option":"project","repeated":false,"required":false}],"path":["chatgpt-desktop","threads"],"routeId":"cli:chatgpt-desktop/threads"},{"aliases":[],"description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","exitCode":"result","options":[{"key":"message","kind":"string","option":"message","positional":1,"repeated":false,"required":true},{"key":"name","kind":"string","option":"name","positional":0,"repeated":false,"required":true},{"key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["claude","send"],"routeId":"cli:claude/send"},{"aliases":[],"description":"Managed Grok/Codex bridge respond.","exitCode":"result","options":[{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","key":"answersJson","kind":"string","option":"answers-json","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"choices":["accept","decline","cancel"],"key":"decision","kind":"enum","option":"decision","repeated":false,"required":false},{"key":"exchangeId","kind":"string","option":"exchange-id","repeated":false,"required":false},{"key":"generation","kind":"string","option":"generation","repeated":false,"required":true},{"key":"interactionId","kind":"string","option":"interaction-id","repeated":false,"required":true},{"key":"threadId","kind":"string","option":"thread-id","repeated":false,"required":true},{"key":"turnId","kind":"string","option":"turn-id","repeated":false,"required":true}],"path":["codex","bridge","respond"],"routeId":"cli:codex/bridge/respond"},{"aliases":[],"description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","exitCode":"result","options":[{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","key":"lifetimeMs","kind":"number","option":"lifetime-ms","repeated":false,"required":false}],"path":["codex","bridge","run"],"routeId":"cli:codex/bridge/run"},{"aliases":[],"description":"Managed Grok/Codex bridge start.","exitCode":"result","options":[{"choices":["steer","reject"],"key":"busyPolicy","kind":"enum","option":"busy-policy","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"grokTarget","kind":"string","option":"grok-target","positional":0,"repeated":false,"required":true},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false}],"path":["codex","bridge","start"],"routeId":"cli:codex/bridge/start"},{"aliases":[],"description":"Managed Grok/Codex bridge status.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","bridge","status"],"routeId":"cli:codex/bridge/status"},{"aliases":[],"description":"Managed Grok/Codex bridge stop.","exitCode":"result","options":[{"key":"all","kind":"boolean","option":"all","repeated":false,"required":false},{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"worker","kind":"boolean","option":"worker","repeated":false,"required":false}],"path":["codex","bridge","stop"],"routeId":"cli:codex/bridge/stop"},{"aliases":[],"description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","exitCode":"result","options":[{"choices":["install","uninstall","status"],"description":"install | uninstall | status","key":"action","kind":"enum","option":"action","positional":0,"repeated":false,"required":true}],"path":["codex","desktop-shim"],"routeId":"cli:codex/desktop-shim"},{"aliases":[],"description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","exitCode":"result","options":[{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","key":"cursor","kind":"string","option":"cursor","repeated":false,"required":false},{"description":"Max threads to list (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false}],"path":["codex","list-threads"],"routeId":"cli:codex/list-threads"},{"aliases":[],"description":"Start a new Codex thread in --cwd, optionally with --model, --effort and a message.","exitCode":"result","options":[{"key":"cwd","kind":"string","option":"cwd","repeated":false,"required":true},{"choices":["none","minimal","low","medium","high","xhigh"],"key":"effort","kind":"enum","option":"effort","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":0,"repeated":true,"required":false},{"key":"model","kind":"string","option":"model","repeated":false,"required":false}],"path":["codex","new"],"routeId":"cli:codex/new"},{"aliases":[],"description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","exitCode":"result","options":[{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true}],"path":["codex","queue"],"routeId":"cli:codex/queue"},{"aliases":[],"description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"choices":["none","minimal","low","medium","high","xhigh"],"key":"effort","kind":"enum","option":"effort","repeated":false,"required":false},{"key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Required active-turn guard for steer; stale guards reject.","key":"expectedTurnId","kind":"string","option":"expected-turn-id","repeated":false,"required":false},{"key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"key":"model","kind":"string","option":"model","repeated":false,"required":false},{"key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"replyToGrok","kind":"string","option":"reply-to-grok","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-7200000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"wait","kind":"boolean","option":"wait","repeated":false,"required":false},{"choices":["reject","queue","steer"],"key":"whenBusy","kind":"enum","option":"when-busy","repeated":false,"required":false}],"path":["codex","send"],"routeId":"cli:codex/send"},{"aliases":[],"description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","exitCode":"result","options":[],"path":["codex","status"],"routeId":"cli:codex/status"},{"aliases":[],"description":"Bounded Codex wait observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Reply budget: 1-4194304 bytes.","key":"maxOutputBytes","kind":"number","option":"max-output-bytes","repeated":false,"required":false},{"key":"messageId","kind":"string","option":"message-id","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-7200000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false},{"key":"turnId","kind":"string","option":"turn-id","positional":1,"repeated":false,"required":true}],"path":["codex","wait"],"routeId":"cli:codex/wait"},{"aliases":[],"description":"Bounded Codex watch observation; never interrupts execution.","exitCode":"result","options":[{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Maximum observed events: 1-500.","key":"maxEvents","kind":"number","option":"max-events","repeated":false,"required":false},{"key":"threadId","kind":"string","option":"thread-id","positional":0,"repeated":false,"required":true},{"description":"Observation timeout: 1-600000 milliseconds.","key":"timeoutMs","kind":"number","option":"timeout-ms","repeated":false,"required":false}],"path":["codex","watch"],"routeId":"cli:codex/watch"},{"aliases":[],"description":"Show which agents root and auth sources gbot can see.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["doctor"],"routeId":"cli:doctor"},{"aliases":[],"description":"Add a bot to a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","add"],"routeId":"cli:groups/add"},{"aliases":[],"description":"Create a Grok Bot group.","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true},{"key":"name","kind":"string","option":"name","repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","create"],"routeId":"cli:groups/create"},{"aliases":[],"description":"Delete a group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","delete"],"routeId":"cli:groups/delete"},{"aliases":[],"description":"Show one group by id or name.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","get"],"routeId":"cli:groups/get"},{"aliases":[],"description":"List Grok Bot groups.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["groups","list"],"routeId":"cli:groups/list"},{"aliases":[],"description":"Show members of a group (same payload as groups get).","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true}],"path":["groups","members"],"routeId":"cli:groups/members"},{"aliases":[],"description":"Remove a bot from a group.","exitCode":"zero","options":[{"key":"bot","kind":"string","option":"bot","positional":1,"repeated":false,"required":true},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true}],"path":["groups","remove"],"routeId":"cli:groups/remove"},{"aliases":[],"description":"Replace a group's member list.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"group","kind":"string","option":"group","positional":0,"repeated":false,"required":true},{"description":"Member bot id or name (repeatable)","key":"member","kind":"string","option":"member","repeated":true,"required":true}],"path":["groups","set"],"routeId":"cli:groups/set"},{"aliases":[],"description":"Update a group profile (members stay on set/add/remove).","exitCode":"zero","options":[{"key":"avatarColor","kind":"string","option":"avatar-color","repeated":false,"required":false},{"key":"avatarShape","kind":"string","option":"avatar-shape","repeated":false,"required":false},{"key":"description","kind":"string","option":"description","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"key":"hidden","kind":"string","option":"hidden","repeated":false,"required":false},{"key":"name","kind":"string","option":"name","repeated":false,"required":false},{"key":"notify","kind":"string","option":"notify","repeated":false,"required":false},{"description":"Group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":true},{"key":"title","kind":"string","option":"title","repeated":false,"required":false}],"path":["groups","update"],"routeId":"cli:groups/update"},{"aliases":[],"description":"Read the opt-in local JSONL history without contacting the gateway.","exitCode":"zero","options":[{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Maximum matching rows (1 or more)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Print the history file path","key":"path","kind":"boolean","option":"path","repeated":false,"required":false},{"description":"Bot or group id or name","key":"ref","kind":"string","option":"ref","positional":0,"repeated":false,"required":false},{"description":"Case-insensitive message text filter","key":"search","kind":"string","option":"search","repeated":false,"required":false}],"path":["history"],"routeId":"cli:history"},{"aliases":[],"description":"Send a message to a Grok Bot bot or group by name or id.","exitCode":"result","options":[{"key":"bindingId","kind":"string","option":"binding-id","repeated":false,"required":false},{"key":"codexThreadId","kind":"string","option":"codex-thread-id","repeated":false,"required":false},{"description":"Stable correlation id for multi-hop replies","key":"correlationId","kind":"string","option":"correlation-id","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Prepend the [gbot …] header","key":"envelope","kind":"boolean","option":"envelope","repeated":false,"required":false},{"key":"expectedCwd","kind":"string","option":"expected-cwd","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","key":"hop","kind":"number","option":"hop","repeated":false,"required":false},{"key":"message","kind":"string","option":"message","positional":1,"repeated":true,"required":true},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"choices":["auto","manual"],"key":"replyMode","kind":"enum","option":"reply-mode","repeated":false,"required":false},{"description":"Prior message id this send replies to","key":"replyTo","kind":"string","option":"reply-to","repeated":false,"required":false},{"key":"requestId","kind":"string","option":"request-id","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["send"],"routeId":"cli:send"},{"aliases":[],"description":"Add a SKILL.md to the shared skill library. Every bot sees it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"SKILL.md file, or a directory holding one","key":"path","kind":"string","option":"path","positional":0,"repeated":false,"required":true}],"path":["skills","add"],"routeId":"cli:skills/add"},{"aliases":[],"description":"List the skill library every bot in this Grok Bot shares.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false}],"path":["skills","list"],"routeId":"cli:skills/list"},{"aliases":[],"description":"Remove a library skill by id or name. Every bot loses it.","exitCode":"zero","options":[{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Skill id or name","key":"skill","kind":"string","option":"skill","positional":0,"repeated":false,"required":true}],"path":["skills","remove"],"routeId":"cli:skills/remove"},{"aliases":[],"description":"Read the most recent messages in a Grok Bot bot or group thread.","exitCode":"zero","options":[{"description":"Return entries after this opaque entry id","key":"after","kind":"string","option":"after","repeated":false,"required":false},{"description":"Agents directory for --files mode","key":"dir","kind":"string","option":"dir","repeated":false,"required":false},{"description":"Force the on-disk agents store","key":"files","kind":"boolean","option":"files","repeated":false,"required":false},{"description":"Show full entry text in human output","key":"full","kind":"boolean","option":"full","repeated":false,"required":false},{"description":"Force the live gateway","key":"gateway","kind":"boolean","option":"gateway","repeated":false,"required":false},{"description":"Directory containing history.jsonl","key":"historyDir","kind":"string","option":"history-dir","repeated":false,"required":false},{"description":"How many trailing entries to return (1-200)","key":"limit","kind":"number","option":"limit","repeated":false,"required":false},{"description":"Skip local history for this command","key":"noHistory","kind":"boolean","option":"no-history","repeated":false,"required":false},{"description":"Read one rooted thread by message id","key":"root","kind":"string","option":"root","repeated":false,"required":false},{"key":"target","kind":"string","option":"target","positional":0,"repeated":false,"required":true}],"path":["thread"],"routeId":"cli:thread"}],"mode":"generated","routes":[{"contract":"contract:src/cli/approvals/list.tsx#inputJsonSchema","description":"List current Grok approval cards (latest 200 entries).","id":"cli:approvals/list","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/list.tsx"},{"contract":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","description":"Explicit user decision: accept a Grok request once or decline; never grant persistent permissions.","id":"cli:approvals/respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/approvals/respond.tsx"},{"contract":"contract:src/cli/bots/create.tsx#inputJsonSchema","description":"Create a Grok Bot bot.","id":"cli:bots/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/create.tsx"},{"contract":"contract:src/cli/bots/delete.tsx#inputJsonSchema","description":"Delete a bot or group by id or name.","id":"cli:bots/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/delete.tsx"},{"contract":"contract:src/cli/bots/get.tsx#inputJsonSchema","description":"Show one bot or group by id or name.","id":"cli:bots/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/get.tsx"},{"contract":"contract:src/cli/bots/list.tsx#inputJsonSchema","description":"List Grok Bot bots (not groups).","id":"cli:bots/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/list.tsx"},{"contract":"contract:src/cli/bots/update.tsx#inputJsonSchema","description":"Update a bot or group profile.","id":"cli:bots/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/bots/update.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","description":"Discover ChatGPT Desktop hosts and modelProviders at runtime (never hardcode). Always includes local plus every remote-thread-summaries-v3:; Providers come from distinct thread/list and remote-summary values.","id":"cli:chatgpt-desktop/hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/hosts.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","description":"Read a ChatGPT Desktop thread via app-server (turns/list); CDP DOM is fallback only.","id":"cli:chatgpt-desktop/read","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page","type":"string"},"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/read.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","description":"Search ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/search","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a prior search page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/search.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","description":"Send to ChatGPT Desktop via CDP composer. Omit --thread-id for a new chat; --project prefers Start new chat in .","id":"cli:chatgpt-desktop/send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/send.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","description":"Probe local ChatGPT Desktop CDP on 127.0.0.1 and report app-server availability for list/deep-read.","id":"cli:chatgpt-desktop/status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/status.tsx"},{"contract":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","description":"List local + remote-control ChatGPT Desktop threads. --host and --model-provider accept any string (see gbot chatgpt-desktop hosts); not enums.","id":"cli:chatgpt-desktop/threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/chatgpt-desktop/threads.tsx"},{"contract":"contract:src/cli/claude/send.tsx#inputJsonSchema","description":"Send to an explicitly enabled live Claude Code channel and wait for its reply.","id":"cli:claude/send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/claude/send.tsx"},{"contract":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge respond.","id":"cli:codex/bridge/respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/respond.tsx"},{"contract":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","description":"Run a bounded foreground relay (up to 23 hours). Use the packaged gbot-relay.mjs script for unlimited service lifetime.","id":"cli:codex/bridge/run","inputSchema":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/run.tsx"},{"contract":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge start.","id":"cli:codex/bridge/start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/start.tsx"},{"contract":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge status.","id":"cli:codex/bridge/status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/status.tsx"},{"contract":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","description":"Managed Grok/Codex bridge stop.","id":"cli:codex/bridge/stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/bridge/stop.tsx"},{"contract":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","description":"Install, remove, or check the ChatGPT Desktop shim: a CODEX_CLI_PATH wrapper that bridges Desktop stdio onto the managed Codex daemon (stock app-server proxy hangs). macOS persists via LaunchAgent; always fails open to real Codex.","id":"cli:codex/desktop-shim","inputSchema":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/desktop-shim.tsx"},{"contract":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","description":"List Codex daemon-managed threads (all modelProviders; pages via --cursor / nextCursor).","id":"cli:codex/list-threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/list-threads.tsx"},{"contract":"contract:src/cli/codex/new.tsx#inputJsonSchema","description":"Start a new Codex thread in --cwd, optionally with --model, --effort and a message.","id":"cli:codex/new","inputSchema":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/new.tsx"},{"contract":"contract:src/cli/codex/queue.tsx#inputJsonSchema","description":"List the experimental Codex thread queue (GROK_BOT_CODEX_EXPERIMENTAL=1).","id":"cli:codex/queue","inputSchema":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/queue.tsx"},{"contract":"contract:src/cli/codex/send.tsx#inputJsonSchema","description":"Send to Codex; acceptance is distinct from completion. Options precede threadId.","id":"cli:codex/send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/send.tsx"},{"contract":"contract:src/cli/codex/status.tsx#inputJsonSchema","description":"Probe the local Codex app-server daemon. Exit 0 only when it is usable.","id":"cli:codex/status","inputSchema":{"additionalProperties":false,"properties":{},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/status.tsx"},{"contract":"contract:src/cli/codex/wait.tsx#inputJsonSchema","description":"Bounded Codex wait observation; never interrupts execution.","id":"cli:codex/wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/wait.tsx"},{"contract":"contract:src/cli/codex/watch.tsx#inputJsonSchema","description":"Bounded Codex watch observation; never interrupts execution.","id":"cli:codex/watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/codex/watch.tsx"},{"contract":"contract:src/cli/doctor.tsx#inputJsonSchema","description":"Show which agents root and auth sources gbot can see.","id":"cli:doctor","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/doctor.tsx"},{"contract":"contract:src/cli/groups/add.tsx#inputJsonSchema","description":"Add a bot to a group.","id":"cli:groups/add","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/add.tsx"},{"contract":"contract:src/cli/groups/create.tsx#inputJsonSchema","description":"Create a Grok Bot group.","id":"cli:groups/create","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/create.tsx"},{"contract":"contract:src/cli/groups/delete.tsx#inputJsonSchema","description":"Delete a group by id or name.","id":"cli:groups/delete","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/delete.tsx"},{"contract":"contract:src/cli/groups/get.tsx#inputJsonSchema","description":"Show one group by id or name.","id":"cli:groups/get","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/get.tsx"},{"contract":"contract:src/cli/groups/list.tsx#inputJsonSchema","description":"List Grok Bot groups.","id":"cli:groups/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/list.tsx"},{"contract":"contract:src/cli/groups/members.tsx#inputJsonSchema","description":"Show members of a group (same payload as groups get).","id":"cli:groups/members","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/members.tsx"},{"contract":"contract:src/cli/groups/remove.tsx#inputJsonSchema","description":"Remove a bot from a group.","id":"cli:groups/remove","inputSchema":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/remove.tsx"},{"contract":"contract:src/cli/groups/set.tsx#inputJsonSchema","description":"Replace a group's member list.","id":"cli:groups/set","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/set.tsx"},{"contract":"contract:src/cli/groups/update.tsx#inputJsonSchema","description":"Update a group profile (members stay on set/add/remove).","id":"cli:groups/update","inputSchema":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/groups/update.tsx"},{"contract":"contract:src/cli/history.tsx#inputJsonSchema","description":"Read the opt-in local JSONL history without contacting the gateway.","id":"cli:history","inputSchema":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/history.tsx"},{"contract":"contract:src/cli/send.tsx#inputJsonSchema","description":"Send a message to a Grok Bot bot or group by name or id.","id":"cli:send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/send.tsx"},{"contract":"contract:src/cli/skills/add.tsx#inputJsonSchema","description":"Add a SKILL.md to the shared skill library. Every bot sees it.","id":"cli:skills/add","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/add.tsx"},{"contract":"contract:src/cli/skills/list.tsx#inputJsonSchema","description":"List the skill library every bot in this Grok Bot shares.","id":"cli:skills/list","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/list.tsx"},{"contract":"contract:src/cli/skills/remove.tsx#inputJsonSchema","description":"Remove a library skill by id or name. Every bot loses it.","id":"cli:skills/remove","inputSchema":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/skills/remove.tsx"},{"contract":"contract:src/cli/thread.tsx#inputJsonSchema","description":"Read the most recent messages in a Grok Bot bot or group thread.","id":"cli:thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"cli","provenance":{"kind":"conventional"},"source":"src/cli/thread.tsx"}]},"contracts":[{"id":"contract:src/cli/approvals/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/list.tsx"},"routes":["cli:approvals/list"]},{"id":"contract:src/cli/approvals/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/approvals/respond.tsx"},"routes":["cli:approvals/respond"]},{"id":"contract:src/cli/bots/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/create.tsx"},"routes":["cli:bots/create"]},{"id":"contract:src/cli/bots/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/delete.tsx"},"routes":["cli:bots/delete"]},{"id":"contract:src/cli/bots/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/get.tsx"},"routes":["cli:bots/get"]},{"id":"contract:src/cli/bots/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/list.tsx"},"routes":["cli:bots/list"]},{"id":"contract:src/cli/bots/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Bot or group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/bots/update.tsx"},"routes":["cli:bots/update"]},{"id":"contract:src/cli/chatgpt-desktop/hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/hosts.tsx"},"routes":["cli:chatgpt-desktop/hosts"]},{"id":"contract:src/cli/chatgpt-desktop/read.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page","type":"string"},"full":{"default":false,"type":"boolean"},"limit":{"description":"Recent default 100; full default 2000","type":"number"},"openTimeoutMs":{"default":90000,"type":"number"},"port":{"type":"number"},"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/read.tsx"},"routes":["cli:chatgpt-desktop/read"]},{"id":"contract:src/cli/chatgpt-desktop/search.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a prior search page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max matches (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"},"query":{"type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/search.tsx"},"routes":["cli:chatgpt-desktop/search"]},{"id":"contract:src/cli/chatgpt-desktop/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"type":"string"},"text":{"items":{"type":"string"},"type":"array"},"threadId":{"type":"string"},"unarchive":{"description":"Explicitly unarchive an existing archived thread before sending.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/send.tsx"},"routes":["cli:chatgpt-desktop/send"]},{"id":"contract:src/cli/chatgpt-desktop/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/status.tsx"},"routes":["cli:chatgpt-desktop/status"]},{"id":"contract:src/cli/chatgpt-desktop/threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page","type":"string"},"groupBy":{"description":"Group results by host (grouping mode, not a host id)","enum":["host"],"type":"string"},"host":{"description":"Any string: all (default), local, or a hostId/friendly name from `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"limit":{"default":50,"description":"Max threads (1-200)","type":"number"},"modelProvider":{"description":"Any modelProvider id (app-server modelProviders pass-through). Omit = all. See `gbot chatgpt-desktop hosts`. Not an enum.","type":"string"},"port":{"description":"Local CDP port","type":"number"},"project":{"description":"Project label or projectId filter.","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/chatgpt-desktop/threads.tsx"},"routes":["cli:chatgpt-desktop/threads"]},{"id":"contract:src/cli/claude/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/claude/send.tsx"},"routes":["cli:claude/send"]},{"id":"contract:src/cli/codex/bridge/respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/respond.tsx"},"routes":["cli:codex/bridge/respond"]},{"id":"contract:src/cli/codex/bridge/run.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"lifetimeMs":{"description":"Foreground lifetime in milliseconds (100..82800000; default 23h).","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/run.tsx"},"routes":["cli:codex/bridge/run"]},{"id":"contract:src/cli/codex/bridge/start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/start.tsx"},"routes":["cli:codex/bridge/start"]},{"id":"contract:src/cli/codex/bridge/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/status.tsx"},"routes":["cli:codex/bridge/status"]},{"id":"contract:src/cli/codex/bridge/stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/bridge/stop.tsx"},"routes":["cli:codex/bridge/stop"]},{"id":"contract:src/cli/codex/desktop-shim.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"action":{"description":"install | uninstall | status","enum":["install","uninstall","status"],"type":"string"}},"required":["action"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/desktop-shim.tsx"},"routes":["cli:codex/desktop-shim"]},{"id":"contract:src/cli/codex/list-threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque pagination cursor from a previous nextCursor (may start with -)","type":"string"},"limit":{"default":20,"description":"Max threads to list (1-200)","type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/list-threads.tsx"},"routes":["cli:codex/list-threads"]},{"id":"contract:src/cli/codex/new.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/new.tsx"},"routes":["cli:codex/new"]},{"id":"contract:src/cli/codex/queue.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"threadId":{"type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/queue.tsx"},"routes":["cli:codex/queue"]},{"id":"contract:src/cli/codex/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"description":"Required active-turn guard for steer; stale guards reject.","type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"wait":{"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/send.tsx"},"routes":["cli:codex/send"]},{"id":"contract:src/cli/codex/status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/status.tsx"},"routes":["cli:codex/status"]},{"id":"contract:src/cli/codex/wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/wait.tsx"},"routes":["cli:codex/wait"]},{"id":"contract:src/cli/codex/watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/codex/watch.tsx"},"routes":["cli:codex/watch"]},{"id":"contract:src/cli/doctor.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/doctor.tsx"},"routes":["cli:doctor"]},{"id":"contract:src/cli/groups/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/add.tsx"},"routes":["cli:groups/add"]},{"id":"contract:src/cli/groups/create.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"},"name":{"type":"string"},"title":{"type":"string"}},"required":["name","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/create.tsx"},"routes":["cli:groups/create"]},{"id":"contract:src/cli/groups/delete.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/delete.tsx"},"routes":["cli:groups/delete"]},{"id":"contract:src/cli/groups/get.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/get.tsx"},"routes":["cli:groups/get"]},{"id":"contract:src/cli/groups/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/list.tsx"},"routes":["cli:groups/list"]},{"id":"contract:src/cli/groups/members.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"ref":{"description":"Group id or name","type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/members.tsx"},"routes":["cli:groups/members"]},{"id":"contract:src/cli/groups/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bot":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"}},"required":["group","bot"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/remove.tsx"},"routes":["cli:groups/remove"]},{"id":"contract:src/cli/groups/set.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"group":{"type":"string"},"member":{"description":"Member bot id or name (repeatable)","items":{"type":"string"},"type":"array"}},"required":["group","member"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/set.tsx"},"routes":["cli:groups/set"]},{"id":"contract:src/cli/groups/update.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"avatarColor":{"type":"string"},"avatarShape":{"type":"string"},"description":{"type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"hidden":{"type":"string"},"name":{"type":"string"},"notify":{"type":"string"},"ref":{"description":"Group id or name","type":"string"},"title":{"type":"string"}},"required":["ref"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/groups/update.tsx"},"routes":["cli:groups/update"]},{"id":"contract:src/cli/history.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"Maximum matching rows (1 or more)","type":"number"},"path":{"description":"Print the history file path","type":"boolean"},"ref":{"description":"Bot or group id or name","type":"string"},"search":{"description":"Case-insensitive message text filter","type":"string"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/history.tsx"},"routes":["cli:history"]},{"id":"contract:src/cli/send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"description":"Stable correlation id for multi-hop replies","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"envelope":{"description":"Prepend the [gbot …] header","type":"boolean"},"expectedCwd":{"type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"hop":{"description":"Hop count; refused at GROK_BOT_MAX_HOPS","type":"number"},"message":{"items":{"type":"string"},"type":"array"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"replyMode":{"enum":["auto","manual"],"type":"string"},"replyTo":{"description":"Prior message id this send replies to","type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/send.tsx"},"routes":["cli:send"]},{"id":"contract:src/cli/skills/add.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"path":{"description":"SKILL.md file, or a directory holding one","type":"string"}},"required":["path"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/add.tsx"},"routes":["cli:skills/add"]},{"id":"contract:src/cli/skills/list.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/list.tsx"},"routes":["cli:skills/list"]},{"id":"contract:src/cli/skills/remove.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"skill":{"description":"Skill id or name","type":"string"}},"required":["skill"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/skills/remove.tsx"},"routes":["cli:skills/remove"]},{"id":"contract:src/cli/thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Return entries after this opaque entry id","type":"string"},"dir":{"description":"Agents directory for --files mode","type":"string"},"files":{"description":"Force the on-disk agents store","type":"boolean"},"full":{"description":"Show full entry text in human output","type":"boolean"},"gateway":{"description":"Force the live gateway","type":"boolean"},"historyDir":{"description":"Directory containing history.jsonl","type":"string"},"limit":{"default":40,"description":"How many trailing entries to return (1-200)","type":"number"},"noHistory":{"description":"Skip local history for this command","type":"boolean"},"root":{"description":"Read one rooted thread by message id","type":"string"},"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/cli/thread.tsx"},"routes":["cli:thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_hosts"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_list_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_open_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page. Keep threadId and full unchanged.","type":"string"},"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_read_thread"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the previous search page; keep query and filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_search_threads"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_send"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_status"]},{"id":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},"routes":["tool:grok-bot/chatgpt_desktop_wait_reply"]},{"id":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/claude_send.tsx"},"routes":["tool:grok-bot/claude_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_new.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"type":"string"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_new.tsx"},"routes":["tool:grok-bot/codex_new"]},{"id":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_send.tsx"},"routes":["tool:grok-bot/codex_send"]},{"id":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_threads.tsx"},"routes":["tool:grok-bot/codex_threads"]},{"id":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_wait.tsx"},"routes":["tool:grok-bot/codex_wait"]},{"id":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/codex_watch.tsx"},"routes":["tool:grok-bot/codex_watch"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},"routes":["tool:grok-bot/gbot_bridge_start"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},"routes":["tool:grok-bot/gbot_bridge_status"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},"routes":["tool:grok-bot/gbot_bridge_stop"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},"routes":["tool:grok-bot/gbot_codex_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},"routes":["tool:grok-bot/gbot_grok_approvals"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},"routes":["tool:grok-bot/gbot_grok_respond"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_send.tsx"},"routes":["tool:grok-bot/gbot_send"]},{"id":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","input":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"origin":{"binding":"inputJsonSchema","module":"src/mcp/grok-bot/tools/gbot_thread.tsx"},"routes":["tool:grok-bot/gbot_thread"]}],"digest":"c0f041a6aedf5b5e8760c0125a69225707c642edb094259fa080c580fe89668c","events":[],"layouts":[],"providers":[],"scripts":[{"id":"script:gbot-relay","kind":"script","provenance":{"kind":"conventional"},"source":"src/scripts/gbot-relay.ts"}],"servers":[{"id":"mcp:grok-bot","mode":"generated","name":"grok-bot","routes":[{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx#inputJsonSchema","description":"Discover local, remote-control environment ids, managed SSH hosts, and modelProvider ids. hostName is null when Desktop has no real display name. Use hostId or label in list/search filters; remote thread ids must be read on the owning host. warnings report provider discovery failures.","id":"tool:grok-bot/chatgpt_desktop_list_hosts","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_hosts.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx#inputJsonSchema","description":"List one sorted Desktop inventory without duplicate rows. Pass nextCursor as cursor with unchanged filters until null; pages fill limit unless the MCP byte budget binds. A changed/expired inventory cursor requires restarting. Display titles are capped at 200 characters with titleTruncated:true. Filter by dynamic hostId/hostName, modelProvider, or Desktop project label/projectId; projectRootPath identifies the resolved workspace. Rows expose local:, location, hostId, and provider; remote rows require their owning host for reading or sending. Backend and warnings identify partial sources.","id":"tool:grok-bot/chatgpt_desktop_list_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior page; keep filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum threads per page.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId. Dynamic string, not an enum.","type":"string"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_list_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx#inputJsonSchema","description":"Navigate Desktop to an existing local: or bare conversation id, even when the row is absent from the sidebar. Archived routes return archived:true without unarchiving; read them with chatgpt_desktop_read_thread. A remote-control id is owned by its hostId and cannot be opened on this Mac. CDP_UNREACHABLE means Desktop must be reachable locally.","id":"tool:grok-bot/chatgpt_desktop_open_thread","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"description":"Maximum time to wait for the requested conversation (1-600000 ms).","type":"number"},"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"},"threadId":{"description":"local: or bare durable id. Temporary local:client-new-thread:* works only while selected; remote ids require their owning host.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_open_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx#inputJsonSchema","description":"Read a local:, bare durable id, or selected temporary local:client-new-thread:* id. Pass nextCursor back as cursor with the same threadId/full mode until complete:true. Pages stop at a byte budget; oversized turns use ordered continuation fragments with stable turnKey and field offsets, without dropping text. Archived threads remain readable. Warnings explain partial pages or app-server errors. REMOTE_THREAD_NOT_LOADED includes the owning hostId: call on that host.","id":"tool:grok-bot/chatgpt_desktop_read_thread","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the prior read page. Keep threadId and full unchanged.","type":"string"},"full":{"description":"When true, page from the start through the complete history (up to 2000 turns by default); otherwise return the most recent 100 turns by default. Explicit limit bounds either mode.","type":"boolean"},"limit":{"type":"number"},"openTimeoutMs":{"description":"Max wait for Loading task… to clear after opening (default 90000).","type":"number"},"port":{"type":"number"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:* temporary id. Remote ids return REMOTE_THREAD_NOT_LOADED with hostId.","type":"string"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_read_thread.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx#inputJsonSchema","description":"Search full Desktop thread metadata by case-insensitive substring. Display titles are capped at 200 characters with titleTruncated:true. Pass nextCursor as cursor with unchanged query and filters to retrieve all matches. Dynamic hostId/hostName, modelProvider, and project filters apply. Remote results identify hostId and cannot be read on this Mac.","id":"tool:grok-bot/chatgpt_desktop_search_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from the previous search page; keep query and filters unchanged.","type":"string"},"groupBy":{"description":"When \"host\", also return groups[] keyed by host (grouping mode, not a host id).","enum":["host"],"type":"string"},"host":{"description":"Any string filter for machine/location. Reserved: \"all\" (default), \"local\". Otherwise a hostId or friendly name discovered at runtime — see chatgpt_desktop_list_hosts. Not an enum; new machines/connections appear with no code change.","type":"string"},"limit":{"default":50,"description":"Maximum matches.","type":"number"},"modelProvider":{"description":"Any modelProvider id string (passed through to app-server modelProviders). Omit for all providers. Discovered values: see chatgpt_desktop_list_hosts. Not an enum.","type":"string"},"port":{"type":"number"},"project":{"description":"Match a Desktop project label or app-server projectId.","type":"string"},"query":{"description":"Case-insensitive substring over thread metadata.","type":"string"}},"required":["query"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_search_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx#inputJsonSchema","description":"Send once through local Desktop CDP. With threadId, accept local:, bare durable id, or currently selected local:client-new-thread:*; remote ids must be sent on their hostId. Omit threadId and project for a new chat outside projects; omit threadId and set project for a new chat inside it. The empty view and project scope are checked before typing. New-thread receipts include temporaryThreadId when seen and return durable local: once resolved. ARCHIVED_THREAD rejects without sending; unarchive:true explicitly unarchives that existing thread first. PROJECT_UNAVAILABLE identifies a disabled project action or missing configured root; NEW_CHAT_NAVIGATION_FAILED reports an unchanged view promptly. CDP_UNREACHABLE and COMPOSER_HAS_DRAFT require operator inspection, not blind retry.","id":"tool:grok-bot/chatgpt_desktop_send","inputSchema":{"additionalProperties":false,"properties":{"openTimeoutMs":{"type":"number"},"port":{"type":"number"},"project":{"description":"With threadId omitted, create the new chat inside this project. Omit for a new chat outside projects.","type":"string"},"text":{"type":"string"},"threadId":{"description":"local:, bare durable id, or selected local:client-new-thread:*; omit for a new chat.","type":"string"},"unarchive":{"default":false,"description":"Existing threadId only: explicitly call thread/unarchive after ARCHIVED_THREAD, then retry the send once. Never implicit.","type":"boolean"}},"required":["text"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx#inputJsonSchema","description":"Check local ChatGPT Desktop CDP before send, wait, or open. reachable:false and exitCode:1 mean CDP is down even if appServerFallback.reachable is true; list/search/read may still work through app-server. There is no remote CDP transport.","id":"tool:grok-bot/chatgpt_desktop_status","inputSchema":{"additionalProperties":false,"properties":{"port":{"description":"Local CDP port (default 9222 or CHATGPT_DESKTOP_CDP_PORT).","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx#inputJsonSchema","description":"After chatgpt_desktop_send, wait for the selected Desktop reply over CDP. Accept the returned durable local: or the temporary local:client-new-thread:* while selected; omit threadId only when staying on the same selected chat. Returns reply, durable threadId and conversationId. timeout is not proof the send failed; CDP_UNREACHABLE requires Desktop recovery. Remote ids must be handled on their hostId.","id":"tool:grok-bot/chatgpt_desktop_wait_reply","inputSchema":{"additionalProperties":false,"properties":{"port":{"type":"number"},"threadId":{"description":"Durable local:, bare id, or selected local:client-new-thread:* from send.","type":"string"},"timeoutMs":{"default":120000,"type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/chatgpt_desktop_wait_reply.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/claude_send.tsx#inputJsonSchema","description":"Send to a named, opted-in live Claude Code channel and wait for its reply. Unknown delivery must not be retried automatically. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/claude_send","inputSchema":{"additionalProperties":false,"properties":{"message":{"type":"string"},"name":{"type":"string"},"timeoutMs":{"type":"number"}},"required":["name","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/claude_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_new.tsx#inputJsonSchema","description":"Start a new Codex thread on this machine in cwd, optionally sending its first message. Codex must run locally on the same machine as gbot.","id":"tool:grok-bot/codex_new","inputSchema":{"additionalProperties":false,"properties":{"cwd":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"expectedCwd":{"type":"string"},"message":{"type":"string"},"model":{"type":"string"}},"required":["cwd"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_new.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_send.tsx#inputJsonSchema","description":"Send to a Codex thread. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport. With replyToGrok or bindingId, managed delivery returns the terminal answer to Grok automatically. Otherwise optional wait observes completion and explicit steer requires expectedTurnId. Acceptance is not completion.","id":"tool:grok-bot/codex_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"correlationId":{"type":"string"},"effort":{"enum":["none","minimal","low","medium","high","xhigh"],"type":"string"},"envelope":{"type":"boolean"},"expectedCwd":{"type":"string"},"expectedTurnId":{"type":"string"},"hop":{"type":"number"},"maxOutputBytes":{"type":"number"},"message":{"type":"string"},"model":{"type":"string"},"replyTo":{"type":"string"},"replyToGrok":{"type":"string"},"requestId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"type":"number"},"wait":{"default":false,"type":"boolean"},"whenBusy":{"enum":["reject","queue","steer"],"type":"string"}},"required":["threadId","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_threads.tsx#inputJsonSchema","description":"Discover a bounded page of Codex daemon threads. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_threads","inputSchema":{"additionalProperties":false,"properties":{"cursor":{"description":"Opaque nextCursor from a previous page.","type":"string"},"limit":{"description":"Maximum threads in this page: 1-200. Pass modelProviders:[] internally so every provider is included; use cursor/nextCursor to page.","type":"number"}},"required":[],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_threads.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_wait.tsx#inputJsonSchema","description":"Explicit diagnostic observation of one Codex turn; returns execution and final reply without interrupting it. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_wait","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxOutputBytes":{"description":"Reply budget: 1-4194304 bytes.","type":"number"},"messageId":{"type":"string"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-7200000 milliseconds.","type":"number"},"turnId":{"type":"string"}},"required":["threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_wait.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/codex_watch.tsx#inputJsonSchema","description":"Watch bounded Codex thread events for diagnostics without answering approvals. Runs on the user's registered machine via its local socket, not the Grok Bot box. From the box, use Grok Bot Shell with a machineId to run gbot there after codex app-server daemon start or bootstrap; gbot has no remote transport.","id":"tool:grok-bot/codex_watch","inputSchema":{"additionalProperties":false,"properties":{"expectedCwd":{"type":"string"},"maxEvents":{"description":"Maximum observed events: 1-500.","type":"number"},"threadId":{"type":"string"},"timeoutMs":{"description":"Observation timeout: 1-600000 milliseconds.","type":"number"}},"required":["threadId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/codex_watch.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_start.tsx#inputJsonSchema","description":"Link a Grok conversation to Codex once. New visible Grok messages arrive automatically and Codex final answers return to Grok.","id":"tool:grok-bot/gbot_bridge_start","inputSchema":{"additionalProperties":false,"properties":{"busyPolicy":{"enum":["steer","reject"],"type":"string"},"codexThreadId":{"type":"string"},"expectedCwd":{"type":"string"},"grokTarget":{"type":"string"},"requestId":{"type":"string"}},"required":["grokTarget"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_start.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_status.tsx#inputJsonSchema","description":"Inspect worker health, route coverage, bounded receipts and scoped pending operator interactions.","id":"tool:grok-bot/gbot_bridge_status","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"limit":{"type":"number"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_status.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_bridge_stop.tsx#inputJsonSchema","description":"Stop a binding without deleting receipts or interrupting Codex. all stops all bindings; worker explicitly shuts down the worker.","id":"tool:grok-bot/gbot_bridge_stop","inputSchema":{"additionalProperties":false,"properties":{"all":{"type":"boolean"},"bindingId":{"type":"string"},"worker":{"type":"boolean"}},"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_bridge_stop.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_codex_respond.tsx#inputJsonSchema","description":"Explicit operator response to a current scoped Codex interaction. Supports only one-time accept/decline/cancel or exact question-ID answers. Never auto-approve.","id":"tool:grok-bot/gbot_codex_respond","inputSchema":{"additionalProperties":false,"properties":{"answersJson":{"description":"JSON object mapping each advertised question ID to {\"answers\":[\"answer\"]}; exact IDs required.","type":"string"},"bindingId":{"type":"string"},"decision":{"enum":["accept","decline","cancel"],"type":"string"},"exchangeId":{"type":"string"},"generation":{"type":"string"},"interactionId":{"type":"string"},"threadId":{"type":"string"},"turnId":{"type":"string"}},"required":["interactionId","generation","threadId","turnId"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_codex_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_approvals.tsx#inputJsonSchema","description":"List pending auto-review and local-tool approval cards in the latest 200 entries for a Grok bot. Older or unsupported requests require the owning Grok UI.","id":"tool:grok-bot/gbot_grok_approvals","inputSchema":{"additionalProperties":false,"properties":{"target":{"type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_approvals.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_grok_respond.tsx#inputJsonSchema","description":"Only after an explicit user decision: accept one current Grok approval once or decline it. Exact target, entryId and approval requestId required. Never auto-approve or grant persistent permissions. Success acknowledges response delivery, not execution.","id":"tool:grok-bot/gbot_grok_respond","inputSchema":{"additionalProperties":false,"properties":{"decision":{"enum":["accept","decline"],"type":"string"},"entryId":{"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","entryId","requestId","decision"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_grok_respond.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_send.tsx#inputJsonSchema","description":"Send to Grok Bot. Native Codex calls automatically receive replies in their originating thread; send once and continue work. Without a native source, supply codexThreadId or use manual gbot_thread reading.","id":"tool:grok-bot/gbot_send","inputSchema":{"additionalProperties":false,"properties":{"bindingId":{"type":"string"},"codexThreadId":{"type":"string"},"correlationId":{"type":"string"},"expectedCwd":{"type":"string"},"hop":{"description":"Explicit chain hop count, refused at the configured bound.","type":"number"},"message":{"type":"string"},"replyMode":{"enum":["auto","manual"],"type":"string"},"requestId":{"type":"string"},"target":{"type":"string"}},"required":["target","message"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_send.tsx"},{"contract":"contract:src/mcp/grok-bot/tools/gbot_thread.tsx#inputJsonSchema","description":"Read a bounded Grok Bot thread tail. Returns a small receipt by default; pass the last cursor as after for an exclusive client-side delta, or full:true to include bounded entry text.","id":"tool:grok-bot/gbot_thread","inputSchema":{"additionalProperties":false,"properties":{"after":{"description":"Opaque cursor from the previous call. Returns entries strictly after it; an unknown cursor resets with a bounded snapshot.","type":"string"},"full":{"default":false,"description":"Return entries with text up to bounded budgets (20k chars per entry, 200k total). Every entry reports truncated/fullLength; read any remainder with `gbot thread --full` / `--json` on the machine.","type":"boolean"},"limit":{"default":40,"description":"How many trailing entries to inspect (1-200). Entries are returned only with full:true.","type":"number"},"target":{"description":"Bot or group name or id, for example \"General\".","type":"string"}},"required":["target"],"type":"object"},"kind":"tool","provenance":{"kind":"conventional"},"serverId":"mcp:grok-bot","source":"src/mcp/grok-bot/tools/gbot_thread.tsx"}]}]},"runtime":{"node":"22.19.0"}} diff --git a/artifact/bin/gbot-flight.mjs b/artifact/bin/gbot-flight.mjs index 72d9fac..1060ee8 100644 --- a/artifact/bin/gbot-flight.mjs +++ b/artifact/bin/gbot-flight.mjs @@ -12079,7 +12079,7 @@ var __webpack_modules__ = { return new _errors_js__rspack_import_1.Rg(threadId, remote.hostId, remote.hostName); } const hostId = (0, _remote_threads_js__rspack_import_2.XI)(threadId); - return new _errors_js__rspack_import_1.Rg(threadId, hostId, null); + if (hostId) return new _errors_js__rspack_import_1.Rg(threadId, hostId, null); } if (error instanceof Error) return error; return new Error(message || `app-server error for thread ${threadId}`); @@ -13361,6 +13361,7 @@ var __webpack_modules__ = { discoverModelProviders: _app_server_fallback_js__rspack_import_2.X }; const MERGED_LIST_CURSOR = 'desktop-merged-list-v1:'; + const MERGED_SEARCH_CURSOR = 'desktop-merged-search-v1:'; class ChatGptDesktopFacade { #cdp; #port; @@ -13411,13 +13412,19 @@ var __webpack_modules__ = { } else { snapshot = await this.#buildListSnapshot(options, filters); } - if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop list cursor is out of range'); + return this.#pageSnapshot(snapshot, offset, limit, options, MERGED_LIST_CURSOR); + } + #pageSnapshot(snapshot, offset, limit, options, prefix, query) { + if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop cursor is out of range'); const host = normalizeHostFilter(options.host); const rows = []; const base = { backend: snapshot.backend, limit, host, + ...query !== undefined ? { + query + } : {}, ...options.modelProvider?.trim() ? { modelProvider: options.modelProvider.trim() } : {}, @@ -13437,7 +13444,7 @@ var __webpack_modules__ = { const probe = { ...base, threads: candidate, - nextCursor: MERGED_LIST_CURSOR, + nextCursor: prefix, ...options.groupBy === 'host' ? { groups: groupThreadsByHost(candidate) } : {}, @@ -13453,7 +13460,7 @@ var __webpack_modules__ = { if ((0, _payload_budget_js__rspack_import_8.sQ)({ ...base, threads: minimal, - nextCursor: MERGED_LIST_CURSOR, + nextCursor: prefix, ...options.groupBy === 'host' ? { groups: groupThreadsByHost(minimal) } : {}, @@ -13466,17 +13473,17 @@ var __webpack_modules__ = { rows.push(row); } const nextOffset = offset + rows.length; - const nextCursor = nextOffset < snapshot.rows.length ? (0, _payload_budget_js__rspack_import_8.oI)(MERGED_LIST_CURSOR, { + const nextCursor = nextOffset < snapshot.rows.length ? (0, _payload_budget_js__rspack_import_8.oI)(prefix, { fingerprint: snapshot.fingerprint, offset: nextOffset, port: this.#port, - filters + filters: snapshot.filters }) : null; const warnings = [ ...snapshot.warnings ]; if (rows.length < Math.min(limit, snapshot.rows.length - offset)) { - warnings.push('List page stopped at the MCP byte budget; continue with nextCursor'); + warnings.push(`${query === undefined ? 'List' : 'Search'} page stopped at the MCP byte budget; continue with nextCursor`); } return { ...base, @@ -13497,6 +13504,7 @@ var __webpack_modules__ = { let appComplete = false; const seenCursors = new Set(); const modelProviders = modelProvidersFromFilter(options.modelProvider); + let appSucceeded = false; try { for(let page = 0; page < 400; page++){ const out = await this.#fallbacks.listThreads({ @@ -13504,6 +13512,7 @@ var __webpack_modules__ = { cursor: appCursor, modelProviders }); + appSucceeded = true; appRows.push(...out.threads); if (out.warnings) warnings.push(...out.warnings); if (!out.nextCursor) { @@ -13537,7 +13546,11 @@ var __webpack_modules__ = { limit: appRows.length, threads: appRows }; - const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const base = appSucceeded ? cdpList ? mergeThreadLists(appList, cdpList) : appList : cdpList ?? { + backend: 'remote-state', + limit: 0, + threads: [] + }; const merged = finalizeThreadList({ ...base, threads: (0, _project_state_js__rspack_import_6.j)(base.threads) @@ -13582,15 +13595,18 @@ var __webpack_modules__ = { } async listHosts() { const remotes = this.#listRemotes(); - const cdpRows = typeof this.#cdp.listThreads === 'function' ? (await this.#tryCdpList({ + const cdpList = typeof this.#cdp.listThreads === 'function' ? await this.#tryCdpList({ limit: 200 - }))?.threads ?? [] : []; + }) : null; + const cdpRows = cdpList?.threads ?? []; let localThreadCount = 0; + let appSucceeded = false; try { const local = await this.#fallbacks.listThreads({ limit: 25, modelProviders: [] }); + appSucceeded = true; localThreadCount = local.threads.length; } catch { localThreadCount = 0; @@ -13721,7 +13737,7 @@ var __webpack_modules__ = { hostsSource, modelProviders, modelProvidersSource, - backend: cdpRows.length ? remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp' : remotes.length ? 'app-server+remote-state' : 'app-server', + backend: appSucceeded ? cdpRows.length ? remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp' : remotes.length ? 'app-server+remote-state' : 'app-server' : cdpRows.length ? remotes.length ? 'cdp+remote-state' : 'cdp' : 'remote-state', ...warnings.length ? { warnings } : {} @@ -13729,76 +13745,117 @@ var __webpack_modules__ = { } async searchThreads(options) { const limit = options.limit ?? 50; - const host = normalizeHostFilter(options.host); + const filters = JSON.stringify({ + query: options.query, + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || null, + project: options.project?.trim() || null, + groupBy: options.groupBy ?? null + }); + let snapshot; + let offset = 0; + if (options.cursor) { + const state = (0, _payload_budget_js__rspack_import_8.i3)(MERGED_SEARCH_CURSOR, options.cursor); + if (state.port !== this.#port || state.filters !== filters || !Number.isSafeInteger(state.offset) || state.offset < 1 || typeof state.fingerprint !== 'string') { + throw new Error('ChatGPT Desktop search cursor does not match the port, query or filters'); + } + offset = state.offset; + snapshot = this.#listSnapshots.get(state.fingerprint) ?? await this.#buildSearchSnapshot(options, filters); + if (snapshot.fingerprint !== state.fingerprint || snapshot.filters !== filters || snapshot.port !== this.#port) { + throw new Error('ChatGPT Desktop search results changed; restart without a cursor'); + } + } else { + snapshot = await this.#buildSearchSnapshot(options, filters); + } + return this.#pageSnapshot(snapshot, offset, limit, options, MERGED_SEARCH_CURSOR, options.query); + } + async #buildSearchSnapshot(options, filters) { const modelProviders = modelProvidersFromFilter(options.modelProvider); + const appRows = []; + const warnings = []; + const seenCursors = new Set(); + let appCursor; + let appSucceeded = false; + let appError; try { - const appList = await this.#fallbacks.searchThreads({ - query: options.query, - limit, - cursor: options.cursor, - modelProviders - }); - const cdpList = options.cursor ? null : await this.#tryCdpList({ - limit - }); - const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; - const appMatches = new Set(appList.threads.map((thread)=>thread.threadId)); - const withRemotes = finalizeThreadList({ - ...base, - threads: (0, _project_state_js__rspack_import_6.j)(base.threads) - }, { - limit: 10000, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - remotes: options.cursor ? [] : (0, _project_state_js__rspack_import_6.j)(this.#listRemotes()) - }); - const needle = options.query.trim().toLowerCase(); - const filtered = { - ...withRemotes, - query: options.query, - threads: withRemotes.threads.filter((thread)=>appMatches.has(thread.threadId) || threadMatchesQuery(thread, needle)) - }; - const result = finalizeThreadList(filtered, { - limit, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - groupBy: options.groupBy, - remotes: [] - }); - return result; - } catch (appError) { - if (options.cursor) throw appError; - const cdpList = await this.#tryCdpList({ - limit - }); - const remotes = this.#listRemotes(); - if (!cdpList && !remotes.length) throw appError; - const needle = options.query.trim().toLowerCase(); - const filtered = { - ...cdpList ?? { - backend: 'app-server', - limit - }, - query: options.query, - threads: (0, _project_state_js__rspack_import_6.j)(cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) - }; - const result = finalizeThreadList(filtered, { - limit, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - groupBy: options.groupBy, - remotes: (0, _project_state_js__rspack_import_6.j)(remotes).filter((thread)=>threadMatchesQuery(thread, needle)) - }); - return { - ...result, - warnings: [ - `App-server search failed: ${appError instanceof Error ? appError.message : String(appError)}` - ] - }; + for(let page = 0; page < 400; page++){ + const out = await this.#fallbacks.searchThreads({ + query: options.query, + limit: 200, + cursor: appCursor, + modelProviders + }); + appSucceeded = true; + appRows.push(...out.threads); + if (out.warnings) warnings.push(...out.warnings); + if (!out.nextCursor) break; + if (seenCursors.has(out.nextCursor)) throw new Error('App-server search returned a repeated cursor'); + seenCursors.add(out.nextCursor); + appCursor = out.nextCursor; + if (page === 399) warnings.push('App-server search stopped after 400 pages'); + } + } catch (error) { + appError = error; + warnings.push(`App-server search failed: ${error instanceof Error ? error.message : String(error)}`); + } + const cdpList = await this.#tryCdpList({ + limit: 200 + }); + const remotes = (0, _project_state_js__rspack_import_6.j)(this.#listRemotes()); + if (!appSucceeded && !cdpList && !remotes.length) throw appError; + const appList = { + backend: 'app-server', + limit: appRows.length, + threads: appRows + }; + const base = appSucceeded ? cdpList ? mergeThreadLists(appList, cdpList) : appList : cdpList ?? { + backend: 'remote-state', + limit: 0, + threads: [] + }; + const appMatches = new Set(appRows.map((thread)=>(0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId)); + const merged = finalizeThreadList({ + ...base, + threads: (0, _project_state_js__rspack_import_6.j)(base.threads) + }, { + limit: Number.MAX_SAFE_INTEGER, + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, + remotes + }); + const needle = options.query.trim().toLowerCase(); + const rows = [ + ...new Map(merged.threads.filter((thread)=>appMatches.has((0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId) || threadMatchesQuery(thread, needle)).map((thread)=>[ + (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId, + thread + ])).values() + ]; + rows.sort(compareDesktopThreads); + const fingerprint = (0, node_crypto__rspack_import_0.createHash)('sha256').update(JSON.stringify({ + filters, + port: this.#port, + rows: rows.map((row)=>[ + row.threadId, + row.updatedAt, + row.location, + row.hostId + ]) + })).digest('base64url'); + const snapshot = { + fingerprint, + port: this.#port, + filters, + createdAt: Date.now(), + rows, + backend: merged.backend, + warnings + }; + for (const [key, value] of this.#listSnapshots){ + if (Date.now() - value.createdAt > 15 * 60000 || this.#listSnapshots.size >= 8) this.#listSnapshots.delete(key); } + this.#listSnapshots.set(fingerprint, snapshot); + return snapshot; } async readThread(options) { const limit = options.limit ?? (options.full ? 2000 : 100); diff --git a/artifact/bin/gbot.mjs b/artifact/bin/gbot.mjs index fbbaaed..e076601 100755 --- a/artifact/bin/gbot.mjs +++ b/artifact/bin/gbot.mjs @@ -10487,7 +10487,7 @@ var __webpack_modules__ = { return new _errors_js__rspack_import_1.Rg(threadId, remote.hostId, remote.hostName); } const hostId = (0, _remote_threads_js__rspack_import_2.XI)(threadId); - return new _errors_js__rspack_import_1.Rg(threadId, hostId, null); + if (hostId) return new _errors_js__rspack_import_1.Rg(threadId, hostId, null); } if (error instanceof Error) return error; return new Error(message || `app-server error for thread ${threadId}`); @@ -11769,6 +11769,7 @@ var __webpack_modules__ = { discoverModelProviders: _app_server_fallback_js__rspack_import_2.X }; const MERGED_LIST_CURSOR = 'desktop-merged-list-v1:'; + const MERGED_SEARCH_CURSOR = 'desktop-merged-search-v1:'; class ChatGptDesktopFacade { #cdp; #port; @@ -11819,13 +11820,19 @@ var __webpack_modules__ = { } else { snapshot = await this.#buildListSnapshot(options, filters); } - if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop list cursor is out of range'); + return this.#pageSnapshot(snapshot, offset, limit, options, MERGED_LIST_CURSOR); + } + #pageSnapshot(snapshot, offset, limit, options, prefix, query) { + if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop cursor is out of range'); const host = normalizeHostFilter(options.host); const rows = []; const base = { backend: snapshot.backend, limit, host, + ...query !== undefined ? { + query + } : {}, ...options.modelProvider?.trim() ? { modelProvider: options.modelProvider.trim() } : {}, @@ -11845,7 +11852,7 @@ var __webpack_modules__ = { const probe = { ...base, threads: candidate, - nextCursor: MERGED_LIST_CURSOR, + nextCursor: prefix, ...options.groupBy === 'host' ? { groups: groupThreadsByHost(candidate) } : {}, @@ -11861,7 +11868,7 @@ var __webpack_modules__ = { if ((0, _payload_budget_js__rspack_import_8.sQ)({ ...base, threads: minimal, - nextCursor: MERGED_LIST_CURSOR, + nextCursor: prefix, ...options.groupBy === 'host' ? { groups: groupThreadsByHost(minimal) } : {}, @@ -11874,17 +11881,17 @@ var __webpack_modules__ = { rows.push(row); } const nextOffset = offset + rows.length; - const nextCursor = nextOffset < snapshot.rows.length ? (0, _payload_budget_js__rspack_import_8.oI)(MERGED_LIST_CURSOR, { + const nextCursor = nextOffset < snapshot.rows.length ? (0, _payload_budget_js__rspack_import_8.oI)(prefix, { fingerprint: snapshot.fingerprint, offset: nextOffset, port: this.#port, - filters + filters: snapshot.filters }) : null; const warnings = [ ...snapshot.warnings ]; if (rows.length < Math.min(limit, snapshot.rows.length - offset)) { - warnings.push('List page stopped at the MCP byte budget; continue with nextCursor'); + warnings.push(`${query === undefined ? 'List' : 'Search'} page stopped at the MCP byte budget; continue with nextCursor`); } return { ...base, @@ -11905,6 +11912,7 @@ var __webpack_modules__ = { let appComplete = false; const seenCursors = new Set(); const modelProviders = modelProvidersFromFilter(options.modelProvider); + let appSucceeded = false; try { for(let page = 0; page < 400; page++){ const out = await this.#fallbacks.listThreads({ @@ -11912,6 +11920,7 @@ var __webpack_modules__ = { cursor: appCursor, modelProviders }); + appSucceeded = true; appRows.push(...out.threads); if (out.warnings) warnings.push(...out.warnings); if (!out.nextCursor) { @@ -11945,7 +11954,11 @@ var __webpack_modules__ = { limit: appRows.length, threads: appRows }; - const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const base = appSucceeded ? cdpList ? mergeThreadLists(appList, cdpList) : appList : cdpList ?? { + backend: 'remote-state', + limit: 0, + threads: [] + }; const merged = finalizeThreadList({ ...base, threads: (0, _project_state_js__rspack_import_6.j)(base.threads) @@ -11990,15 +12003,18 @@ var __webpack_modules__ = { } async listHosts() { const remotes = this.#listRemotes(); - const cdpRows = typeof this.#cdp.listThreads === 'function' ? (await this.#tryCdpList({ + const cdpList = typeof this.#cdp.listThreads === 'function' ? await this.#tryCdpList({ limit: 200 - }))?.threads ?? [] : []; + }) : null; + const cdpRows = cdpList?.threads ?? []; let localThreadCount = 0; + let appSucceeded = false; try { const local = await this.#fallbacks.listThreads({ limit: 25, modelProviders: [] }); + appSucceeded = true; localThreadCount = local.threads.length; } catch { localThreadCount = 0; @@ -12129,7 +12145,7 @@ var __webpack_modules__ = { hostsSource, modelProviders, modelProvidersSource, - backend: cdpRows.length ? remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp' : remotes.length ? 'app-server+remote-state' : 'app-server', + backend: appSucceeded ? cdpRows.length ? remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp' : remotes.length ? 'app-server+remote-state' : 'app-server' : cdpRows.length ? remotes.length ? 'cdp+remote-state' : 'cdp' : 'remote-state', ...warnings.length ? { warnings } : {} @@ -12137,76 +12153,117 @@ var __webpack_modules__ = { } async searchThreads(options) { const limit = options.limit ?? 50; - const host = normalizeHostFilter(options.host); + const filters = JSON.stringify({ + query: options.query, + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || null, + project: options.project?.trim() || null, + groupBy: options.groupBy ?? null + }); + let snapshot; + let offset = 0; + if (options.cursor) { + const state = (0, _payload_budget_js__rspack_import_8.i3)(MERGED_SEARCH_CURSOR, options.cursor); + if (state.port !== this.#port || state.filters !== filters || !Number.isSafeInteger(state.offset) || state.offset < 1 || typeof state.fingerprint !== 'string') { + throw new Error('ChatGPT Desktop search cursor does not match the port, query or filters'); + } + offset = state.offset; + snapshot = this.#listSnapshots.get(state.fingerprint) ?? await this.#buildSearchSnapshot(options, filters); + if (snapshot.fingerprint !== state.fingerprint || snapshot.filters !== filters || snapshot.port !== this.#port) { + throw new Error('ChatGPT Desktop search results changed; restart without a cursor'); + } + } else { + snapshot = await this.#buildSearchSnapshot(options, filters); + } + return this.#pageSnapshot(snapshot, offset, limit, options, MERGED_SEARCH_CURSOR, options.query); + } + async #buildSearchSnapshot(options, filters) { const modelProviders = modelProvidersFromFilter(options.modelProvider); + const appRows = []; + const warnings = []; + const seenCursors = new Set(); + let appCursor; + let appSucceeded = false; + let appError; try { - const appList = await this.#fallbacks.searchThreads({ - query: options.query, - limit, - cursor: options.cursor, - modelProviders - }); - const cdpList = options.cursor ? null : await this.#tryCdpList({ - limit - }); - const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; - const appMatches = new Set(appList.threads.map((thread)=>thread.threadId)); - const withRemotes = finalizeThreadList({ - ...base, - threads: (0, _project_state_js__rspack_import_6.j)(base.threads) - }, { - limit: 10000, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - remotes: options.cursor ? [] : (0, _project_state_js__rspack_import_6.j)(this.#listRemotes()) - }); - const needle = options.query.trim().toLowerCase(); - const filtered = { - ...withRemotes, - query: options.query, - threads: withRemotes.threads.filter((thread)=>appMatches.has(thread.threadId) || threadMatchesQuery(thread, needle)) - }; - const result = finalizeThreadList(filtered, { - limit, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - groupBy: options.groupBy, - remotes: [] - }); - return result; - } catch (appError) { - if (options.cursor) throw appError; - const cdpList = await this.#tryCdpList({ - limit - }); - const remotes = this.#listRemotes(); - if (!cdpList && !remotes.length) throw appError; - const needle = options.query.trim().toLowerCase(); - const filtered = { - ...cdpList ?? { - backend: 'app-server', - limit - }, - query: options.query, - threads: (0, _project_state_js__rspack_import_6.j)(cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) - }; - const result = finalizeThreadList(filtered, { - limit, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - groupBy: options.groupBy, - remotes: (0, _project_state_js__rspack_import_6.j)(remotes).filter((thread)=>threadMatchesQuery(thread, needle)) - }); - return { - ...result, - warnings: [ - `App-server search failed: ${appError instanceof Error ? appError.message : String(appError)}` - ] - }; + for(let page = 0; page < 400; page++){ + const out = await this.#fallbacks.searchThreads({ + query: options.query, + limit: 200, + cursor: appCursor, + modelProviders + }); + appSucceeded = true; + appRows.push(...out.threads); + if (out.warnings) warnings.push(...out.warnings); + if (!out.nextCursor) break; + if (seenCursors.has(out.nextCursor)) throw new Error('App-server search returned a repeated cursor'); + seenCursors.add(out.nextCursor); + appCursor = out.nextCursor; + if (page === 399) warnings.push('App-server search stopped after 400 pages'); + } + } catch (error) { + appError = error; + warnings.push(`App-server search failed: ${error instanceof Error ? error.message : String(error)}`); + } + const cdpList = await this.#tryCdpList({ + limit: 200 + }); + const remotes = (0, _project_state_js__rspack_import_6.j)(this.#listRemotes()); + if (!appSucceeded && !cdpList && !remotes.length) throw appError; + const appList = { + backend: 'app-server', + limit: appRows.length, + threads: appRows + }; + const base = appSucceeded ? cdpList ? mergeThreadLists(appList, cdpList) : appList : cdpList ?? { + backend: 'remote-state', + limit: 0, + threads: [] + }; + const appMatches = new Set(appRows.map((thread)=>(0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId)); + const merged = finalizeThreadList({ + ...base, + threads: (0, _project_state_js__rspack_import_6.j)(base.threads) + }, { + limit: Number.MAX_SAFE_INTEGER, + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, + remotes + }); + const needle = options.query.trim().toLowerCase(); + const rows = [ + ...new Map(merged.threads.filter((thread)=>appMatches.has((0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId) || threadMatchesQuery(thread, needle)).map((thread)=>[ + (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId, + thread + ])).values() + ]; + rows.sort(compareDesktopThreads); + const fingerprint = (0, node_crypto__rspack_import_0.createHash)('sha256').update(JSON.stringify({ + filters, + port: this.#port, + rows: rows.map((row)=>[ + row.threadId, + row.updatedAt, + row.location, + row.hostId + ]) + })).digest('base64url'); + const snapshot = { + fingerprint, + port: this.#port, + filters, + createdAt: Date.now(), + rows, + backend: merged.backend, + warnings + }; + for (const [key, value] of this.#listSnapshots){ + if (Date.now() - value.createdAt > 15 * 60000 || this.#listSnapshots.size >= 8) this.#listSnapshots.delete(key); } + this.#listSnapshots.set(fingerprint, snapshot); + return snapshot; } async readThread(options) { const limit = options.limit ?? (options.full ? 2000 : 100); diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs index 8a2d927..ec8d8ab 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e-flight.mjs @@ -8759,7 +8759,7 @@ var __webpack_modules__ = { return new _errors_js__rspack_import_1.Rg(threadId, remote.hostId, remote.hostName); } const hostId = (0, _remote_threads_js__rspack_import_2.XI)(threadId); - return new _errors_js__rspack_import_1.Rg(threadId, hostId, null); + if (hostId) return new _errors_js__rspack_import_1.Rg(threadId, hostId, null); } if (error instanceof Error) return error; return new Error(message || `app-server error for thread ${threadId}`); @@ -10041,6 +10041,7 @@ var __webpack_modules__ = { discoverModelProviders: _app_server_fallback_js__rspack_import_2.X }; const MERGED_LIST_CURSOR = 'desktop-merged-list-v1:'; + const MERGED_SEARCH_CURSOR = 'desktop-merged-search-v1:'; class ChatGptDesktopFacade { #cdp; #port; @@ -10091,13 +10092,19 @@ var __webpack_modules__ = { } else { snapshot = await this.#buildListSnapshot(options, filters); } - if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop list cursor is out of range'); + return this.#pageSnapshot(snapshot, offset, limit, options, MERGED_LIST_CURSOR); + } + #pageSnapshot(snapshot, offset, limit, options, prefix, query) { + if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop cursor is out of range'); const host = normalizeHostFilter(options.host); const rows = []; const base = { backend: snapshot.backend, limit, host, + ...query !== undefined ? { + query + } : {}, ...options.modelProvider?.trim() ? { modelProvider: options.modelProvider.trim() } : {}, @@ -10117,7 +10124,7 @@ var __webpack_modules__ = { const probe = { ...base, threads: candidate, - nextCursor: MERGED_LIST_CURSOR, + nextCursor: prefix, ...options.groupBy === 'host' ? { groups: groupThreadsByHost(candidate) } : {}, @@ -10133,7 +10140,7 @@ var __webpack_modules__ = { if ((0, _payload_budget_js__rspack_import_8.sQ)({ ...base, threads: minimal, - nextCursor: MERGED_LIST_CURSOR, + nextCursor: prefix, ...options.groupBy === 'host' ? { groups: groupThreadsByHost(minimal) } : {}, @@ -10146,17 +10153,17 @@ var __webpack_modules__ = { rows.push(row); } const nextOffset = offset + rows.length; - const nextCursor = nextOffset < snapshot.rows.length ? (0, _payload_budget_js__rspack_import_8.oI)(MERGED_LIST_CURSOR, { + const nextCursor = nextOffset < snapshot.rows.length ? (0, _payload_budget_js__rspack_import_8.oI)(prefix, { fingerprint: snapshot.fingerprint, offset: nextOffset, port: this.#port, - filters + filters: snapshot.filters }) : null; const warnings = [ ...snapshot.warnings ]; if (rows.length < Math.min(limit, snapshot.rows.length - offset)) { - warnings.push('List page stopped at the MCP byte budget; continue with nextCursor'); + warnings.push(`${query === undefined ? 'List' : 'Search'} page stopped at the MCP byte budget; continue with nextCursor`); } return { ...base, @@ -10177,6 +10184,7 @@ var __webpack_modules__ = { let appComplete = false; const seenCursors = new Set(); const modelProviders = modelProvidersFromFilter(options.modelProvider); + let appSucceeded = false; try { for(let page = 0; page < 400; page++){ const out = await this.#fallbacks.listThreads({ @@ -10184,6 +10192,7 @@ var __webpack_modules__ = { cursor: appCursor, modelProviders }); + appSucceeded = true; appRows.push(...out.threads); if (out.warnings) warnings.push(...out.warnings); if (!out.nextCursor) { @@ -10217,7 +10226,11 @@ var __webpack_modules__ = { limit: appRows.length, threads: appRows }; - const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const base = appSucceeded ? cdpList ? mergeThreadLists(appList, cdpList) : appList : cdpList ?? { + backend: 'remote-state', + limit: 0, + threads: [] + }; const merged = finalizeThreadList({ ...base, threads: (0, _project_state_js__rspack_import_6.j)(base.threads) @@ -10262,15 +10275,18 @@ var __webpack_modules__ = { } async listHosts() { const remotes = this.#listRemotes(); - const cdpRows = typeof this.#cdp.listThreads === 'function' ? (await this.#tryCdpList({ + const cdpList = typeof this.#cdp.listThreads === 'function' ? await this.#tryCdpList({ limit: 200 - }))?.threads ?? [] : []; + }) : null; + const cdpRows = cdpList?.threads ?? []; let localThreadCount = 0; + let appSucceeded = false; try { const local = await this.#fallbacks.listThreads({ limit: 25, modelProviders: [] }); + appSucceeded = true; localThreadCount = local.threads.length; } catch { localThreadCount = 0; @@ -10401,7 +10417,7 @@ var __webpack_modules__ = { hostsSource, modelProviders, modelProvidersSource, - backend: cdpRows.length ? remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp' : remotes.length ? 'app-server+remote-state' : 'app-server', + backend: appSucceeded ? cdpRows.length ? remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp' : remotes.length ? 'app-server+remote-state' : 'app-server' : cdpRows.length ? remotes.length ? 'cdp+remote-state' : 'cdp' : 'remote-state', ...warnings.length ? { warnings } : {} @@ -10409,76 +10425,117 @@ var __webpack_modules__ = { } async searchThreads(options) { const limit = options.limit ?? 50; - const host = normalizeHostFilter(options.host); + const filters = JSON.stringify({ + query: options.query, + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || null, + project: options.project?.trim() || null, + groupBy: options.groupBy ?? null + }); + let snapshot; + let offset = 0; + if (options.cursor) { + const state = (0, _payload_budget_js__rspack_import_8.i3)(MERGED_SEARCH_CURSOR, options.cursor); + if (state.port !== this.#port || state.filters !== filters || !Number.isSafeInteger(state.offset) || state.offset < 1 || typeof state.fingerprint !== 'string') { + throw new Error('ChatGPT Desktop search cursor does not match the port, query or filters'); + } + offset = state.offset; + snapshot = this.#listSnapshots.get(state.fingerprint) ?? await this.#buildSearchSnapshot(options, filters); + if (snapshot.fingerprint !== state.fingerprint || snapshot.filters !== filters || snapshot.port !== this.#port) { + throw new Error('ChatGPT Desktop search results changed; restart without a cursor'); + } + } else { + snapshot = await this.#buildSearchSnapshot(options, filters); + } + return this.#pageSnapshot(snapshot, offset, limit, options, MERGED_SEARCH_CURSOR, options.query); + } + async #buildSearchSnapshot(options, filters) { const modelProviders = modelProvidersFromFilter(options.modelProvider); + const appRows = []; + const warnings = []; + const seenCursors = new Set(); + let appCursor; + let appSucceeded = false; + let appError; try { - const appList = await this.#fallbacks.searchThreads({ - query: options.query, - limit, - cursor: options.cursor, - modelProviders - }); - const cdpList = options.cursor ? null : await this.#tryCdpList({ - limit - }); - const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; - const appMatches = new Set(appList.threads.map((thread)=>thread.threadId)); - const withRemotes = finalizeThreadList({ - ...base, - threads: (0, _project_state_js__rspack_import_6.j)(base.threads) - }, { - limit: 10000, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - remotes: options.cursor ? [] : (0, _project_state_js__rspack_import_6.j)(this.#listRemotes()) - }); - const needle = options.query.trim().toLowerCase(); - const filtered = { - ...withRemotes, - query: options.query, - threads: withRemotes.threads.filter((thread)=>appMatches.has(thread.threadId) || threadMatchesQuery(thread, needle)) - }; - const result = finalizeThreadList(filtered, { - limit, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - groupBy: options.groupBy, - remotes: [] - }); - return result; - } catch (appError) { - if (options.cursor) throw appError; - const cdpList = await this.#tryCdpList({ - limit - }); - const remotes = this.#listRemotes(); - if (!cdpList && !remotes.length) throw appError; - const needle = options.query.trim().toLowerCase(); - const filtered = { - ...cdpList ?? { - backend: 'app-server', - limit - }, - query: options.query, - threads: (0, _project_state_js__rspack_import_6.j)(cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) - }; - const result = finalizeThreadList(filtered, { - limit, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - groupBy: options.groupBy, - remotes: (0, _project_state_js__rspack_import_6.j)(remotes).filter((thread)=>threadMatchesQuery(thread, needle)) - }); - return { - ...result, - warnings: [ - `App-server search failed: ${appError instanceof Error ? appError.message : String(appError)}` - ] - }; + for(let page = 0; page < 400; page++){ + const out = await this.#fallbacks.searchThreads({ + query: options.query, + limit: 200, + cursor: appCursor, + modelProviders + }); + appSucceeded = true; + appRows.push(...out.threads); + if (out.warnings) warnings.push(...out.warnings); + if (!out.nextCursor) break; + if (seenCursors.has(out.nextCursor)) throw new Error('App-server search returned a repeated cursor'); + seenCursors.add(out.nextCursor); + appCursor = out.nextCursor; + if (page === 399) warnings.push('App-server search stopped after 400 pages'); + } + } catch (error) { + appError = error; + warnings.push(`App-server search failed: ${error instanceof Error ? error.message : String(error)}`); + } + const cdpList = await this.#tryCdpList({ + limit: 200 + }); + const remotes = (0, _project_state_js__rspack_import_6.j)(this.#listRemotes()); + if (!appSucceeded && !cdpList && !remotes.length) throw appError; + const appList = { + backend: 'app-server', + limit: appRows.length, + threads: appRows + }; + const base = appSucceeded ? cdpList ? mergeThreadLists(appList, cdpList) : appList : cdpList ?? { + backend: 'remote-state', + limit: 0, + threads: [] + }; + const appMatches = new Set(appRows.map((thread)=>(0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId)); + const merged = finalizeThreadList({ + ...base, + threads: (0, _project_state_js__rspack_import_6.j)(base.threads) + }, { + limit: Number.MAX_SAFE_INTEGER, + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, + remotes + }); + const needle = options.query.trim().toLowerCase(); + const rows = [ + ...new Map(merged.threads.filter((thread)=>appMatches.has((0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId) || threadMatchesQuery(thread, needle)).map((thread)=>[ + (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId, + thread + ])).values() + ]; + rows.sort(compareDesktopThreads); + const fingerprint = (0, node_crypto__rspack_import_0.createHash)('sha256').update(JSON.stringify({ + filters, + port: this.#port, + rows: rows.map((row)=>[ + row.threadId, + row.updatedAt, + row.location, + row.hostId + ]) + })).digest('base64url'); + const snapshot = { + fingerprint, + port: this.#port, + filters, + createdAt: Date.now(), + rows, + backend: merged.backend, + warnings + }; + for (const [key, value] of this.#listSnapshots){ + if (Date.now() - value.createdAt > 15 * 60000 || this.#listSnapshots.size >= 8) this.#listSnapshots.delete(key); } + this.#listSnapshots.set(fingerprint, snapshot); + return snapshot; } async readThread(options) { const limit = options.limit ?? (options.full ? 2000 : 100); diff --git a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs index cd09ae7..d244a3d 100644 --- a/artifact/mcp/mcp-grok-bot-b8c2461e.mjs +++ b/artifact/mcp/mcp-grok-bot-b8c2461e.mjs @@ -7167,7 +7167,7 @@ var __webpack_modules__ = { return new _errors_js__rspack_import_1.Rg(threadId, remote.hostId, remote.hostName); } const hostId = (0, _remote_threads_js__rspack_import_2.XI)(threadId); - return new _errors_js__rspack_import_1.Rg(threadId, hostId, null); + if (hostId) return new _errors_js__rspack_import_1.Rg(threadId, hostId, null); } if (error instanceof Error) return error; return new Error(message || `app-server error for thread ${threadId}`); @@ -8449,6 +8449,7 @@ var __webpack_modules__ = { discoverModelProviders: _app_server_fallback_js__rspack_import_2.X }; const MERGED_LIST_CURSOR = 'desktop-merged-list-v1:'; + const MERGED_SEARCH_CURSOR = 'desktop-merged-search-v1:'; class ChatGptDesktopFacade { #cdp; #port; @@ -8499,13 +8500,19 @@ var __webpack_modules__ = { } else { snapshot = await this.#buildListSnapshot(options, filters); } - if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop list cursor is out of range'); + return this.#pageSnapshot(snapshot, offset, limit, options, MERGED_LIST_CURSOR); + } + #pageSnapshot(snapshot, offset, limit, options, prefix, query) { + if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop cursor is out of range'); const host = normalizeHostFilter(options.host); const rows = []; const base = { backend: snapshot.backend, limit, host, + ...query !== undefined ? { + query + } : {}, ...options.modelProvider?.trim() ? { modelProvider: options.modelProvider.trim() } : {}, @@ -8525,7 +8532,7 @@ var __webpack_modules__ = { const probe = { ...base, threads: candidate, - nextCursor: MERGED_LIST_CURSOR, + nextCursor: prefix, ...options.groupBy === 'host' ? { groups: groupThreadsByHost(candidate) } : {}, @@ -8541,7 +8548,7 @@ var __webpack_modules__ = { if ((0, _payload_budget_js__rspack_import_8.sQ)({ ...base, threads: minimal, - nextCursor: MERGED_LIST_CURSOR, + nextCursor: prefix, ...options.groupBy === 'host' ? { groups: groupThreadsByHost(minimal) } : {}, @@ -8554,17 +8561,17 @@ var __webpack_modules__ = { rows.push(row); } const nextOffset = offset + rows.length; - const nextCursor = nextOffset < snapshot.rows.length ? (0, _payload_budget_js__rspack_import_8.oI)(MERGED_LIST_CURSOR, { + const nextCursor = nextOffset < snapshot.rows.length ? (0, _payload_budget_js__rspack_import_8.oI)(prefix, { fingerprint: snapshot.fingerprint, offset: nextOffset, port: this.#port, - filters + filters: snapshot.filters }) : null; const warnings = [ ...snapshot.warnings ]; if (rows.length < Math.min(limit, snapshot.rows.length - offset)) { - warnings.push('List page stopped at the MCP byte budget; continue with nextCursor'); + warnings.push(`${query === undefined ? 'List' : 'Search'} page stopped at the MCP byte budget; continue with nextCursor`); } return { ...base, @@ -8585,6 +8592,7 @@ var __webpack_modules__ = { let appComplete = false; const seenCursors = new Set(); const modelProviders = modelProvidersFromFilter(options.modelProvider); + let appSucceeded = false; try { for(let page = 0; page < 400; page++){ const out = await this.#fallbacks.listThreads({ @@ -8592,6 +8600,7 @@ var __webpack_modules__ = { cursor: appCursor, modelProviders }); + appSucceeded = true; appRows.push(...out.threads); if (out.warnings) warnings.push(...out.warnings); if (!out.nextCursor) { @@ -8625,7 +8634,11 @@ var __webpack_modules__ = { limit: appRows.length, threads: appRows }; - const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const base = appSucceeded ? cdpList ? mergeThreadLists(appList, cdpList) : appList : cdpList ?? { + backend: 'remote-state', + limit: 0, + threads: [] + }; const merged = finalizeThreadList({ ...base, threads: (0, _project_state_js__rspack_import_6.j)(base.threads) @@ -8670,15 +8683,18 @@ var __webpack_modules__ = { } async listHosts() { const remotes = this.#listRemotes(); - const cdpRows = typeof this.#cdp.listThreads === 'function' ? (await this.#tryCdpList({ + const cdpList = typeof this.#cdp.listThreads === 'function' ? await this.#tryCdpList({ limit: 200 - }))?.threads ?? [] : []; + }) : null; + const cdpRows = cdpList?.threads ?? []; let localThreadCount = 0; + let appSucceeded = false; try { const local = await this.#fallbacks.listThreads({ limit: 25, modelProviders: [] }); + appSucceeded = true; localThreadCount = local.threads.length; } catch { localThreadCount = 0; @@ -8809,7 +8825,7 @@ var __webpack_modules__ = { hostsSource, modelProviders, modelProvidersSource, - backend: cdpRows.length ? remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp' : remotes.length ? 'app-server+remote-state' : 'app-server', + backend: appSucceeded ? cdpRows.length ? remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp' : remotes.length ? 'app-server+remote-state' : 'app-server' : cdpRows.length ? remotes.length ? 'cdp+remote-state' : 'cdp' : 'remote-state', ...warnings.length ? { warnings } : {} @@ -8817,76 +8833,117 @@ var __webpack_modules__ = { } async searchThreads(options) { const limit = options.limit ?? 50; - const host = normalizeHostFilter(options.host); + const filters = JSON.stringify({ + query: options.query, + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || null, + project: options.project?.trim() || null, + groupBy: options.groupBy ?? null + }); + let snapshot; + let offset = 0; + if (options.cursor) { + const state = (0, _payload_budget_js__rspack_import_8.i3)(MERGED_SEARCH_CURSOR, options.cursor); + if (state.port !== this.#port || state.filters !== filters || !Number.isSafeInteger(state.offset) || state.offset < 1 || typeof state.fingerprint !== 'string') { + throw new Error('ChatGPT Desktop search cursor does not match the port, query or filters'); + } + offset = state.offset; + snapshot = this.#listSnapshots.get(state.fingerprint) ?? await this.#buildSearchSnapshot(options, filters); + if (snapshot.fingerprint !== state.fingerprint || snapshot.filters !== filters || snapshot.port !== this.#port) { + throw new Error('ChatGPT Desktop search results changed; restart without a cursor'); + } + } else { + snapshot = await this.#buildSearchSnapshot(options, filters); + } + return this.#pageSnapshot(snapshot, offset, limit, options, MERGED_SEARCH_CURSOR, options.query); + } + async #buildSearchSnapshot(options, filters) { const modelProviders = modelProvidersFromFilter(options.modelProvider); + const appRows = []; + const warnings = []; + const seenCursors = new Set(); + let appCursor; + let appSucceeded = false; + let appError; try { - const appList = await this.#fallbacks.searchThreads({ - query: options.query, - limit, - cursor: options.cursor, - modelProviders - }); - const cdpList = options.cursor ? null : await this.#tryCdpList({ - limit - }); - const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; - const appMatches = new Set(appList.threads.map((thread)=>thread.threadId)); - const withRemotes = finalizeThreadList({ - ...base, - threads: (0, _project_state_js__rspack_import_6.j)(base.threads) - }, { - limit: 10000, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - remotes: options.cursor ? [] : (0, _project_state_js__rspack_import_6.j)(this.#listRemotes()) - }); - const needle = options.query.trim().toLowerCase(); - const filtered = { - ...withRemotes, - query: options.query, - threads: withRemotes.threads.filter((thread)=>appMatches.has(thread.threadId) || threadMatchesQuery(thread, needle)) - }; - const result = finalizeThreadList(filtered, { - limit, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - groupBy: options.groupBy, - remotes: [] - }); - return result; - } catch (appError) { - if (options.cursor) throw appError; - const cdpList = await this.#tryCdpList({ - limit - }); - const remotes = this.#listRemotes(); - if (!cdpList && !remotes.length) throw appError; - const needle = options.query.trim().toLowerCase(); - const filtered = { - ...cdpList ?? { - backend: 'app-server', - limit - }, - query: options.query, - threads: (0, _project_state_js__rspack_import_6.j)(cdpList?.threads ?? []).filter((thread)=>threadMatchesQuery(thread, needle)) - }; - const result = finalizeThreadList(filtered, { - limit, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - groupBy: options.groupBy, - remotes: (0, _project_state_js__rspack_import_6.j)(remotes).filter((thread)=>threadMatchesQuery(thread, needle)) - }); - return { - ...result, - warnings: [ - `App-server search failed: ${appError instanceof Error ? appError.message : String(appError)}` - ] - }; + for(let page = 0; page < 400; page++){ + const out = await this.#fallbacks.searchThreads({ + query: options.query, + limit: 200, + cursor: appCursor, + modelProviders + }); + appSucceeded = true; + appRows.push(...out.threads); + if (out.warnings) warnings.push(...out.warnings); + if (!out.nextCursor) break; + if (seenCursors.has(out.nextCursor)) throw new Error('App-server search returned a repeated cursor'); + seenCursors.add(out.nextCursor); + appCursor = out.nextCursor; + if (page === 399) warnings.push('App-server search stopped after 400 pages'); + } + } catch (error) { + appError = error; + warnings.push(`App-server search failed: ${error instanceof Error ? error.message : String(error)}`); + } + const cdpList = await this.#tryCdpList({ + limit: 200 + }); + const remotes = (0, _project_state_js__rspack_import_6.j)(this.#listRemotes()); + if (!appSucceeded && !cdpList && !remotes.length) throw appError; + const appList = { + backend: 'app-server', + limit: appRows.length, + threads: appRows + }; + const base = appSucceeded ? cdpList ? mergeThreadLists(appList, cdpList) : appList : cdpList ?? { + backend: 'remote-state', + limit: 0, + threads: [] + }; + const appMatches = new Set(appRows.map((thread)=>(0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId)); + const merged = finalizeThreadList({ + ...base, + threads: (0, _project_state_js__rspack_import_6.j)(base.threads) + }, { + limit: Number.MAX_SAFE_INTEGER, + host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || undefined, + project: options.project, + remotes + }); + const needle = options.query.trim().toLowerCase(); + const rows = [ + ...new Map(merged.threads.filter((thread)=>appMatches.has((0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId) || threadMatchesQuery(thread, needle)).map((thread)=>[ + (0, _thread_ids_js__rspack_import_7.nn)(thread.threadId) ?? thread.threadId, + thread + ])).values() + ]; + rows.sort(compareDesktopThreads); + const fingerprint = (0, node_crypto__rspack_import_0.createHash)('sha256').update(JSON.stringify({ + filters, + port: this.#port, + rows: rows.map((row)=>[ + row.threadId, + row.updatedAt, + row.location, + row.hostId + ]) + })).digest('base64url'); + const snapshot = { + fingerprint, + port: this.#port, + filters, + createdAt: Date.now(), + rows, + backend: merged.backend, + warnings + }; + for (const [key, value] of this.#listSnapshots){ + if (Date.now() - value.createdAt > 15 * 60000 || this.#listSnapshots.size >= 8) this.#listSnapshots.delete(key); } + this.#listSnapshots.set(fingerprint, snapshot); + return snapshot; } async readThread(options) { const limit = options.limit ?? (options.full ? 2000 : 100); diff --git a/src/core/chatgpt-desktop/app-server-fallback.ts b/src/core/chatgpt-desktop/app-server-fallback.ts index da22729..0460afb 100644 --- a/src/core/chatgpt-desktop/app-server-fallback.ts +++ b/src/core/chatgpt-desktop/app-server-fallback.ts @@ -655,7 +655,7 @@ function maybeRemoteThreadError(error: unknown, threadId: string): Error { return new RemoteThreadNotLoadedError(threadId, remote.hostId, remote.hostName); } const hostId = findRemoteThreadHostId(threadId); - return new RemoteThreadNotLoadedError(threadId, hostId, null); + if (hostId) return new RemoteThreadNotLoadedError(threadId, hostId, null); } if (error instanceof Error) return error; return new Error(message || `app-server error for thread ${threadId}`); diff --git a/src/core/chatgpt-desktop/facade.ts b/src/core/chatgpt-desktop/facade.ts index f250ae4..7dd5830 100644 --- a/src/core/chatgpt-desktop/facade.ts +++ b/src/core/chatgpt-desktop/facade.ts @@ -56,6 +56,7 @@ const defaultFallbacks: ChatGptDesktopFallbacks = { }; const MERGED_LIST_CURSOR = 'desktop-merged-list-v1:'; +const MERGED_SEARCH_CURSOR = 'desktop-merged-search-v1:'; type ListSnapshot = { fingerprint: string; port: number; @@ -87,6 +88,8 @@ export type ListThreadsOptions = { groupBy?: 'host'; }; +type SearchThreadsOptions = ListThreadsOptions & { query: string }; + /** * ChatGPT Desktop facade (verified against app-server 0.158.0). * @@ -153,11 +156,17 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { } else { snapshot = await this.#buildListSnapshot(options, filters); } - if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop list cursor is out of range'); + return this.#pageSnapshot(snapshot, offset, limit, options, MERGED_LIST_CURSOR); + } + + #pageSnapshot(snapshot: ListSnapshot, offset: number, limit: number, options: ListThreadsOptions, + prefix: string, query?: string): ListThreadsResult { + if (offset > snapshot.rows.length) throw new Error('ChatGPT Desktop cursor is out of range'); const host = normalizeHostFilter(options.host); const rows: ChatGptDesktopThread[] = []; const base = { backend: snapshot.backend, limit, host, + ...(query !== undefined ? { query } : {}), ...(options.modelProvider?.trim() ? { modelProvider: options.modelProvider.trim() } : {}), ...(options.project ? { project: options.project } : {}), ...(options.groupBy === 'host' ? { groupBy: 'host' as const } : {}), @@ -165,14 +174,14 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { for (const source of snapshot.rows.slice(offset, offset + limit)) { let row = source; const candidate = [...rows, row]; - const probe = { ...base, threads: candidate, nextCursor: MERGED_LIST_CURSOR, + const probe = { ...base, threads: candidate, nextCursor: prefix, ...(options.groupBy === 'host' ? { groups: groupThreadsByHost(candidate) } : {}), warnings: snapshot.warnings, exitCode: 0 }; if (serializedBytes(probe) > DESKTOP_RESULT_BUDGET_BYTES) { if (rows.length) break; row = minimalThreadRow(row); const minimal = [row]; - if (serializedBytes({ ...base, threads: minimal, nextCursor: MERGED_LIST_CURSOR, + if (serializedBytes({ ...base, threads: minimal, nextCursor: prefix, ...(options.groupBy === 'host' ? { groups: groupThreadsByHost(minimal) } : {}), warnings: snapshot.warnings, exitCode: 0 }) > DESKTOP_RESULT_BUDGET_BYTES) { throw new Error('ChatGPT Desktop thread row exceeds the MCP result byte budget'); @@ -182,11 +191,11 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { } const nextOffset = offset + rows.length; const nextCursor = nextOffset < snapshot.rows.length - ? encodePageCursor(MERGED_LIST_CURSOR, { fingerprint: snapshot.fingerprint, offset: nextOffset, - port: this.#port, filters }) : null; + ? encodePageCursor(prefix, { fingerprint: snapshot.fingerprint, offset: nextOffset, + port: this.#port, filters: snapshot.filters }) : null; const warnings = [...snapshot.warnings]; if (rows.length < Math.min(limit, snapshot.rows.length - offset)) { - warnings.push('List page stopped at the MCP byte budget; continue with nextCursor'); + warnings.push(`${query === undefined ? 'List' : 'Search'} page stopped at the MCP byte budget; continue with nextCursor`); } return { ...base, threads: rows, nextCursor, ...(options.groupBy === 'host' ? { groups: groupThreadsByHost(rows) } : {}), @@ -200,9 +209,11 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { let appComplete = false; const seenCursors = new Set(); const modelProviders = modelProvidersFromFilter(options.modelProvider); + let appSucceeded = false; try { for (let page = 0; page < 400; page++) { const out = await this.#fallbacks.listThreads({ limit: 200, cursor: appCursor, modelProviders }); + appSucceeded = true; appRows.push(...out.threads); if (out.warnings) warnings.push(...out.warnings); if (!out.nextCursor) { appComplete = true; break; } @@ -227,7 +238,9 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { throw new CdpUnreachableError(warnings[0] ?? 'ChatGPT Desktop listThreads: CDP and app-server unreachable'); } const appList: ListThreadsResult = { backend: 'app-server', limit: appRows.length, threads: appRows }; - const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; + const base = appSucceeded + ? (cdpList ? mergeThreadLists(appList, cdpList) : appList) + : (cdpList ?? { backend: 'remote-state' as const, limit: 0, threads: [] }); const merged = finalizeThreadList({ ...base, threads: resolveThreadProjects(base.threads) }, { limit: Number.MAX_SAFE_INTEGER, host: normalizeHostFilter(options.host), @@ -250,11 +263,14 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { async listHosts(): Promise { const remotes = this.#listRemotes(); - const cdpRows = typeof this.#cdp.listThreads === 'function' - ? (await this.#tryCdpList({ limit: 200 }))?.threads ?? [] : []; + const cdpList = typeof this.#cdp.listThreads === 'function' + ? await this.#tryCdpList({ limit: 200 }) : null; + const cdpRows = cdpList?.threads ?? []; let localThreadCount = 0; + let appSucceeded = false; try { const local = await this.#fallbacks.listThreads({ limit: 25, modelProviders: [] }); + appSucceeded = true; localThreadCount = local.threads.length; } catch { localThreadCount = 0; @@ -363,78 +379,92 @@ export class ChatGptDesktopFacade implements ChatGptDesktopAdapter { hostsSource, modelProviders, modelProvidersSource, - backend: cdpRows.length - ? (remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp') - : (remotes.length ? 'app-server+remote-state' : 'app-server'), + backend: appSucceeded + ? (cdpRows.length ? (remotes.length ? 'app-server+cdp+remote-state' : 'app-server+cdp') + : (remotes.length ? 'app-server+remote-state' : 'app-server')) + : (cdpRows.length ? (remotes.length ? 'cdp+remote-state' : 'cdp') : 'remote-state'), ...(warnings.length ? { warnings } : {}), }; } - async searchThreads(options: { - query: string; - limit?: number; - cursor?: string; - host?: string; - modelProvider?: string; - project?: string; - groupBy?: 'host'; - }): Promise { + async searchThreads(options: SearchThreadsOptions): Promise { const limit = options.limit ?? 50; - const host = normalizeHostFilter(options.host); + const filters = JSON.stringify({ query: options.query, host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || null, project: options.project?.trim() || null, + groupBy: options.groupBy ?? null }); + let snapshot: ListSnapshot; + let offset = 0; + if (options.cursor) { + const state = decodePageCursor<{ fingerprint: string; offset: number; port: number; filters: string }>( + MERGED_SEARCH_CURSOR, options.cursor); + if (state.port !== this.#port || state.filters !== filters || !Number.isSafeInteger(state.offset) + || state.offset < 1 || typeof state.fingerprint !== 'string') { + throw new Error('ChatGPT Desktop search cursor does not match the port, query or filters'); + } + offset = state.offset; + snapshot = this.#listSnapshots.get(state.fingerprint) ?? await this.#buildSearchSnapshot(options, filters); + if (snapshot.fingerprint !== state.fingerprint || snapshot.filters !== filters || snapshot.port !== this.#port) { + throw new Error('ChatGPT Desktop search results changed; restart without a cursor'); + } + } else { + snapshot = await this.#buildSearchSnapshot(options, filters); + } + return this.#pageSnapshot(snapshot, offset, limit, options, MERGED_SEARCH_CURSOR, options.query); + } + + async #buildSearchSnapshot(options: SearchThreadsOptions, filters: string): Promise { const modelProviders = modelProvidersFromFilter(options.modelProvider); + const appRows: ChatGptDesktopThread[] = []; + const warnings: string[] = []; + const seenCursors = new Set(); + let appCursor: string | undefined; + let appSucceeded = false; + let appError: unknown; try { - const appList = await this.#fallbacks.searchThreads({ - query: options.query, - limit, - cursor: options.cursor, - modelProviders, - }); - const cdpList = options.cursor ? null : await this.#tryCdpList({ limit }); - const base = cdpList ? mergeThreadLists(appList, cdpList) : appList; - const appMatches = new Set(appList.threads.map((thread) => thread.threadId)); - const withRemotes = finalizeThreadList({ ...base, threads: resolveThreadProjects(base.threads) }, { - limit: 10_000, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - remotes: options.cursor ? [] : resolveThreadProjects(this.#listRemotes()), - }); - const needle = options.query.trim().toLowerCase(); - const filtered = { - ...withRemotes, - query: options.query, - threads: withRemotes.threads.filter((thread) => appMatches.has(thread.threadId) || threadMatchesQuery(thread, needle)), - }; - const result = finalizeThreadList(filtered, { - limit, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - groupBy: options.groupBy, - remotes: [], - }); - return result; - } catch (appError) { - if (options.cursor) throw appError; - const cdpList = await this.#tryCdpList({ limit }); - const remotes = this.#listRemotes(); - if (!cdpList && !remotes.length) throw appError; - const needle = options.query.trim().toLowerCase(); - const filtered = { - ...(cdpList ?? { backend: 'app-server' as const, limit }), - query: options.query, - threads: resolveThreadProjects(cdpList?.threads ?? []).filter((thread) => threadMatchesQuery(thread, needle)), - }; - const result = finalizeThreadList(filtered, { - limit, - host, - modelProvider: options.modelProvider?.trim() || undefined, - project: options.project, - groupBy: options.groupBy, - remotes: resolveThreadProjects(remotes).filter((thread) => threadMatchesQuery(thread, needle)), - }); - return { ...result, warnings: [`App-server search failed: ${appError instanceof Error ? appError.message : String(appError)}`] }; + for (let page = 0; page < 400; page++) { + const out = await this.#fallbacks.searchThreads({ query: options.query, limit: 200, + cursor: appCursor, modelProviders }); + appSucceeded = true; + appRows.push(...out.threads); + if (out.warnings) warnings.push(...out.warnings); + if (!out.nextCursor) break; + if (seenCursors.has(out.nextCursor)) throw new Error('App-server search returned a repeated cursor'); + seenCursors.add(out.nextCursor); + appCursor = out.nextCursor; + if (page === 399) warnings.push('App-server search stopped after 400 pages'); + } + } catch (error) { + appError = error; + warnings.push(`App-server search failed: ${error instanceof Error ? error.message : String(error)}`); + } + const cdpList = await this.#tryCdpList({ limit: 200 }); + const remotes = resolveThreadProjects(this.#listRemotes()); + if (!appSucceeded && !cdpList && !remotes.length) throw appError; + const appList: ListThreadsResult = { backend: 'app-server', limit: appRows.length, threads: appRows }; + const base = appSucceeded + ? (cdpList ? mergeThreadLists(appList, cdpList) : appList) + : (cdpList ?? { backend: 'remote-state' as const, limit: 0, threads: [] }); + const appMatches = new Set(appRows.map((thread) => toAppServerThreadId(thread.threadId) ?? thread.threadId)); + const merged = finalizeThreadList({ ...base, threads: resolveThreadProjects(base.threads) }, { + limit: Number.MAX_SAFE_INTEGER, host: normalizeHostFilter(options.host), + modelProvider: options.modelProvider?.trim() || undefined, project: options.project, + remotes, + }); + const needle = options.query.trim().toLowerCase(); + const rows = [...new Map(merged.threads + .filter((thread) => appMatches.has(toAppServerThreadId(thread.threadId) ?? thread.threadId) + || threadMatchesQuery(thread, needle)) + .map((thread) => [toAppServerThreadId(thread.threadId) ?? thread.threadId, thread])).values()]; + rows.sort(compareDesktopThreads); + const fingerprint = createHash('sha256').update(JSON.stringify({ filters, port: this.#port, + rows: rows.map((row) => [row.threadId, row.updatedAt, row.location, row.hostId]) })).digest('base64url'); + const snapshot: ListSnapshot = { fingerprint, port: this.#port, filters, createdAt: Date.now(), + rows, backend: merged.backend, warnings }; + for (const [key, value] of this.#listSnapshots) { + if (Date.now() - value.createdAt > 15 * 60_000 || this.#listSnapshots.size >= 8) this.#listSnapshots.delete(key); } + this.#listSnapshots.set(fingerprint, snapshot); + return snapshot; } async readThread(options: { diff --git a/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts b/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts index 5f406cd..9ede747 100644 --- a/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts +++ b/tests/route-unit/chatgpt-desktop-e2e-regressions.test.ts @@ -295,6 +295,66 @@ it('marks a CDP read partial and preserves the app-server failure', async () => }); }); +it('falls back to CDP when a local thread is absent from app-server and remote state', async () => { + const home = mkdtempSync(join(tmpdir(), 'gbot-local-read-')); + const previousHome = process.env.CODEX_HOME; + process.env.CODEX_HOME = home; + try { + const bridge = await import('../../src/core/codex-bridge.js'); + rstest.spyOn(bridge, 'openCodexSession').mockResolvedValue({ client: { + close() {}, + async request() { throw new Error('no rollout found'); }, + } } as never); + const facade = new ChatGptDesktopFacade({ connect: async () => {}, + readThread: async () => ({ threadId: 'local:desktop-only', turns: [], backend: 'cdp', limit: 100, full: false }), + } as unknown as ChatGptDesktopAdapter, 9222, { readThread: appServerReadThread } as never); + expect(await facade.readThread({ threadId: 'local:desktop-only' })).toMatchObject({ + backend: 'cdp', warnings: ['App-server read failed: no rollout found'], + }); + } finally { + if (previousHome === undefined) delete process.env.CODEX_HOME; + else process.env.CODEX_HOME = previousHome; + rmSync(home, { recursive: true, force: true }); + } +}); + +it('walks every app-server search match when a remote row displaces a full first page', async () => { + const row = (id: string, updatedAt: number) => ({ threadId: `local:${id}`, title: `needle ${id}`, + updatedAt, pinned: false, selected: false, kind: 'codex' }); + const app = [row('a', 3), row('b', 2), row('c', 1)]; + const remote = { ...row('remote', 4), location: 'remote' as const, hostId: 'remote:one', hostName: null }; + const facade = new ChatGptDesktopFacade({ connect: async () => {}, + listThreads: async () => ({ backend: 'cdp', limit: 200, threads: [] }), + } as unknown as ChatGptDesktopAdapter, 9222, { + searchThreads: async ({ cursor }: { cursor?: string }) => ({ backend: 'app-server', limit: 2, + threads: cursor ? app.slice(2) : app.slice(0, 2), nextCursor: cursor ? null : 'next' }), + listRemoteThreads: () => [remote], + } as never); + const ids: string[] = []; + let cursor: string | null | undefined; + do { + const page = await facade.searchThreads({ query: 'needle', limit: 2, ...(cursor ? { cursor } : {}) }); + ids.push(...page.threads.map((thread) => thread.threadId)); + cursor = page.nextCursor; + } while (cursor); + expect(ids).toEqual(['local:remote', 'local:a', 'local:b', 'local:c']); +}); + +it('reports only CDP and remote state when app-server inventory fails', async () => { + const row = (id: string) => ({ threadId: `local:${id}`, title: id, + pinned: false, selected: false, kind: 'codex' }); + const remote = { ...row('remote'), location: 'remote' as const, hostId: 'remote:one', hostName: null }; + const facade = new ChatGptDesktopFacade({ connect: async () => {}, + listThreads: async () => ({ backend: 'cdp', limit: 200, threads: [row('cdp')] }), + } as unknown as ChatGptDesktopAdapter, 9222, { + listThreads: async () => { throw new Error('offline'); }, + listRemoteThreads: () => [remote], listHosts: () => [], + discoverModelProviders: async () => ({ providers: [], source: 'thread/list-distinct', complete: true }), + } as never); + expect((await facade.listThreads()).backend).toBe('cdp+remote-state'); + expect((await facade.listHosts()).backend).toBe('cdp+remote-state'); +}); + it('pages one sorted merged inventory exactly once across app, CDP and remote rows', async () => { const row = (id: string, updatedAt: number) => ({ threadId: `local:${id}`, title: id, updatedAt, pinned: false, selected: false, kind: 'codex' });